diff --git a/front-ui/build/configured./ribica.bundle.js b/front-ui/build/configured./ribica.bundle.js deleted file mode 100644 index e92da98..0000000 --- a/front-ui/build/configured./ribica.bundle.js +++ /dev/null @@ -1,34968 +0,0 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.RIBICA=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;oKategorije -
- {(this.state.section.get('categories') || []).map(function(category){ - return ( -
- - - - -
- {category.name} -
-
-
    - {category.sub_categories.map(function(sc) { - return ( -
  • - {sc.name} -
  • - ) - })} -
- -
- ) - })} -
*/ - - ) - ) - ) - }, - onCategoryClick: function(category, section) { - NavigationActions.goToCategory(new Category(category), section); - - }, - componentWillReceiveProps: function(nextProps) { - var sectionId = this.getParams().id; - ItemActions.loadBestSellingItemsForSection(sectionId); - SectionActions.loadSectionDetails(sectionId); - }, - componentDidMount: function() { - - var sectionId = this.getParams().id; - ItemActions.loadBestSellingItemsForSection(sectionId); - SectionActions.loadSectionDetails(sectionId); - - SectionStore.addChangeListener(this._onSectionChange); - ItemStore.addChangeListener(this._onChange); - }, - componentWillUnmount: function() { - SectionStore.removeChangeListener(this._onSectionChange); - ItemStore.removeChangeListener(this._onChange); - }, - _onSectionChange: function() { - if(this.isMounted()) { - this.setState({ - section: SectionStore.getSectionDetails() - }); - } - }, - _onChange: function() { - if(this.isMounted()) { - - this.setState({items: ItemStore.getBestSellingForSection()}); - } - } -}); - -module.exports = BySection; - - -},{"../../actions/itemActions.js":"/home/senadu/projects/ribica/front-ui/app/actions/itemActions.js","../../actions/navigationActions":"/home/senadu/projects/ribica/front-ui/app/actions/navigationActions.js","../../actions/sectionActions.js":"/home/senadu/projects/ribica/front-ui/app/actions/sectionActions.js","../../models/category":"/home/senadu/projects/ribica/front-ui/app/models/category.js","../../models/itemCollection":"/home/senadu/projects/ribica/front-ui/app/models/itemCollection.js","../../models/section":"/home/senadu/projects/ribica/front-ui/app/models/section.js","../../stores/itemStore":"/home/senadu/projects/ribica/front-ui/app/stores/itemStore.js","../../stores/navigationStore":"/home/senadu/projects/ribica/front-ui/app/stores/navigationStore.js","../../stores/sectionStore":"/home/senadu/projects/ribica/front-ui/app/stores/sectionStore.js","../items/itemList":"/home/senadu/projects/ribica/front-ui/app/components/items/itemList.js","../linkBanner/linkBanner":"/home/senadu/projects/ribica/front-ui/app/components/linkBanner/linkBanner.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/components/browsing/bySubCategory.js":[function(require,module,exports){ -var React = require('react'), - Router = require('react-router'); - -var BySubCategoryActions = require('../../actions/bySubCategoryActions'); -var BySubCategoryStore = require('../../stores/bySubCategoryStore'); -var ItemStore = require('../../stores/itemStore'); -var CategoryStore = require('../../stores/categoryStore'); - -var Globals = require('../../globals'); -var FilterCriteriaSelector = require('./filterCriteriaSelector'); -var AppliedFiltersList = require('./appliedFiltersList'); - -var NavigationActions = require('../../actions/navigationActions'); -var ItemList = require('../items/itemList'); -var BySubCategory = React.createClass({displayName: "BySubCategory", - mixins: [Router.State], - getInitialState : function() { - return BySubCategoryStore.getState(); - }, - onFCClick: function(fc, fcv) { - BySubCategoryActions.filterCriteriaClick(fc, fcv); - }, - removeAppliedFilter: function(name) { - BySubCategoryActions.removeAppliedFilter(name); - }, - onChangePage: function(page) { - BySubCategoryActions.changePage(page); - }, - render : function() { - - return (React.createElement("div", null, - React.createElement("div", {className: "col-md-2"}, - React.createElement(FilterCriteriaSelector, {filterCriterias: this.state.subCategory.get('filter_criterias'), onFCClick: this.onFCClick}) - ), - React.createElement("div", {classname: "col-md-10"}, - - React.createElement("h2", null, - this.state.subCategory.get('name') - ), - - React.createElement("div", null, - React.createElement(AppliedFiltersList, {filters: this.appliedSubCategoryFiltersArray(), onRemove: this.removeAppliedFilter}) - - ), - React.createElement(ItemList, {items: this.state.items, paginationEnabled: true, total: this.state.items.totalCount, limit: this.state.pagination.limit, onPageChange: this.onChangePage, currentOffset: this.state.pagination.offset}) - ) - )) - }, - appliedSubCategoryFiltersArray: function() { - var filters = []; - for(var key in this.state.filter) { - if(this.state.filter.hasOwnProperty(key) && key !== 'limit' && key !== 'offset') { - filters.push({name: key, value: this.state.filter[key]}); - } - } - return filters; - }, - update: function() { - var subCategoryId = this.getParams().id; - var filter = this.getQuery(); - var offset = filter.offset || 0; - var limit = filter.limit || Globals.DefaultPageSize; - - BySubCategoryActions.load(subCategoryId, offset, limit, filter); - }, - componentWillReceiveProps: function() { - this.update(); - }, - componentDidMount: function() { - BySubCategoryStore.addChangeListener(this._onChange); - this.update(); - }, - componentWillUnmount: function() { - BySubCategoryStore.removeChangeListener(this._onChange); - }, - _onChange: function() { - if(this.isMounted()) { - this.setState(BySubCategoryStore.getState()); - } - } -}); - -module.exports = BySubCategory; - - -},{"../../actions/bySubCategoryActions":"/home/senadu/projects/ribica/front-ui/app/actions/bySubCategoryActions.js","../../actions/navigationActions":"/home/senadu/projects/ribica/front-ui/app/actions/navigationActions.js","../../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","../../stores/bySubCategoryStore":"/home/senadu/projects/ribica/front-ui/app/stores/bySubCategoryStore.js","../../stores/categoryStore":"/home/senadu/projects/ribica/front-ui/app/stores/categoryStore.js","../../stores/itemStore":"/home/senadu/projects/ribica/front-ui/app/stores/itemStore.js","../items/itemList":"/home/senadu/projects/ribica/front-ui/app/components/items/itemList.js","./appliedFiltersList":"/home/senadu/projects/ribica/front-ui/app/components/browsing/appliedFiltersList.js","./filterCriteriaSelector":"/home/senadu/projects/ribica/front-ui/app/components/browsing/filterCriteriaSelector.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/components/browsing/filterCriteriaSelector.js":[function(require,module,exports){ -var React = require('react'), - Router = require('react-router'); - -var FilterCriteriaSelector = React.createClass({displayName: "FilterCriteriaSelector", - render : function() { - var self = this; - return (React.createElement("div", null, - - this.props.filterCriterias.map(function(fc) { - return (React.createElement("div", null, - - React.createElement("div", {className: "h4", style: {color: '#cd3071'}}, fc.title), - React.createElement("ul", null, - fc.filter_criteria_values.map(function(fcv) { - return (React.createElement("li", null, - React.createElement("a", {onClick: self.props.onFCClick.bind(self,fc, fcv)}, fcv.filter_text) - )) - }) - ) - )) - }) - - )) - - } -}); - -module.exports = FilterCriteriaSelector; - - -},{"react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/components/cart/addToCart.js":[function(require,module,exports){ -var React = require('react'); -var CartStore = require('../../stores/cartStore.js'); -var CartActions = require('../../actions/cartActions.js'); -var Globals = require('../../globals'); - -var buttonHolderStyle = { - display: 'inline-block' -}; - -var AddToCart = React.createClass({displayName: "AddToCart", - INITIAL_ITEM_COUNT: 1, - render: function() { - var itemCount = this.state.count; - var amountAndAddButton = ( - React.createElement("div", {className: "row-fluid add-to-cart"}, - React.createElement("div", {className: "col-lg-12"}, - React.createElement("button", {className: "btn white_button", onClick: this._onDecreaseClick}, "-"), React.createElement("span", {className: "add-to-cart-count"}, itemCount), - React.createElement("button", {className: "btn white_button", onClick: this._onIncreaseClick}, "+") - ), - React.createElement("div", null, - React.createElement("div", {style: buttonHolderStyle}, React.createElement("button", {className: "btn add-to-cart-button", onClick: this._addToCartClick}, "Ubaci u korpu")) - ) - ) - ); - return amountAndAddButton; - }, - - // Add change listeners to stores - componentDidMount: function() { - CartStore.addChangeListener(this._onChange); - - if(!CartStore.dataStartedLoading()) { - CartActions.load(); - }; - }, - - - getInitialState: function() { - var itemInCart = CartStore.getStateFor(this.props.item.get('id')); - return { - item: itemInCart, - count: this.INITIAL_ITEM_COUNT - } - }, - - - _onChange: function () { - if (this.isMounted()) { - var item = CartStore.getStateFor(this.props.item.get('id')); - this.setState({ item: item, count: this.INITIAL_ITEM_COUNT }); - } - }, - - _onIncreaseClick: function () { - - if (this.state.count < Globals.MaxNumberOfItemsToBeAdded ) { - this.state.count = this.state.count + 1; - this.setState(this.state); - } - }, - - _onDecreaseClick: function () { - - if (this.state.count > 1) { - this.state.count = this.state.count - 1; - this.setState(this.state); - } - }, - - _addToCartClick: function () { - CartActions.addNItems(this.props.item, this.state.count); - }, - - componentWillUnmount: function () { - CartStore.removeChangeListener(this._onChange); - } - -}); - -module.exports = AddToCart; - - -},{"../../actions/cartActions.js":"/home/senadu/projects/ribica/front-ui/app/actions/cartActions.js","../../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","../../stores/cartStore.js":"/home/senadu/projects/ribica/front-ui/app/stores/cartStore.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js"}],"/home/senadu/projects/ribica/front-ui/app/components/cart/cartIcon.js":[function(require,module,exports){ -var React = require('react'); -var CartStore = require('../../stores/cartStore.js'); -var CartActions = require('../../actions/cartActions.js'); -var NavigationActions = require('../../actions/navigationActions.js'); -// var LoginStatus = require('../shared/loginStatus'); -CartTotal = require('./cartTotal'); - - - - -var cartStyle = { - fontSize: '50px' -}; - -var normalizeCount = function(count) { - if (count >= 0 && count < 10) { - return "\u00a0" + count; - } else { - return count; - } -} - -var CartIcon = React.createClass({displayName: "CartIcon", - - render: function() { - - var textNotificationStyle = (this.state.count > 0) ? { display: 'inline-block'} : { display: 'none'} ; - - return ( - React.createElement("div", null, - React.createElement("ul", {className: "nav navbar-nav navbar-right hidden-md hidden-sm hidden-xs"}, - React.createElement("li", {onClick: this._onClick, style: {borderTop: 'solid lightgray 1px', borderBottom: 'solid lightgray 1px', borderLeft: 'solid lightgray 1px', paddingBottom: 22}}, React.createElement("a", null, React.createElement("div", {className: "mycart"}, React.createElement("span", null, normalizeCount(this.state.count))))), - React.createElement("li", {onClick: this._onClick, style: {borderTop: 'solid lightgray 1px', borderBottom: 'solid lightgray 1px', paddingBottom: 2}}, React.createElement("a", {href: "#", style: { paddingRight: '5px', backgroundColor: 'transparent'}}, React.createElement(CartTotal, {items: this.state.items, itemCounts: this.state.itemCounts, deliveryCosts: this.state.deliveryCosts, justMerchandise: true}), " ")), - React.createElement("li", {onClick: this._onClick, style: {borderTop: 'solid lightgray 1px', borderBottom: 'solid lightgray 1px', borderRight: 'solid lightgray 1px'}}, - React.createElement("a", {style: {marginBottom: 10, marginRight: 10}, className: "mybutton", href: "#"}, "Završi narudžbu")) - - ), - - React.createElement("ul", {className: "nav navbar-nav navbar-right hidden-lg"}, - React.createElement("li", {onClick: this._onClick, style: {borderTop: 'solid lightgray 1px', borderBottom: 'solid lightgray 1px', borderLeft: 'solid lightgray 1px', paddingBottom: 22}}, React.createElement("a", null, React.createElement("div", {className: "mycart"}, React.createElement("span", null, normalizeCount(this.state.count))))), - React.createElement("li", {onClick: this._onClick, style: {borderTop: 'solid lightgray 1px', borderBottom: 'solid lightgray 1px',borderRight: 'solid lightgray 1px', paddingBottom: 2}}, React.createElement("a", {href: "#", style: { paddingRight: '5px', backgroundColor: 'transparent'}}, React.createElement(CartTotal, {items: this.state.items, itemCounts: this.state.itemCounts, deliveryCosts: this.state.deliveryCosts, justMerchandise: true}), " ")) - ) - ) - ); - }, - - // Add change listeners to stores - componentDidMount: function() { - CartStore.addChangeListener(this._onChange); - if(!CartStore.dataStartedLoading()) { - CartActions.load(); - }; - }, - - - getInitialState: function() { - var cartState = CartStore.getWholeCartState(); - return cartState; - }, - - _onChange: function () { - if (this.isMounted()) { - - this.setState(CartStore.getWholeCartState()); - } - }, - - componentWillUnmount: function () { - CartStore.removeChangeListener(this._onChange); - }, - - _onClick: function(e) { - NavigationActions.goToCart(); - e.preventDefault(); - } - - -}); - -module.exports = CartIcon; - - -},{"../../actions/cartActions.js":"/home/senadu/projects/ribica/front-ui/app/actions/cartActions.js","../../actions/navigationActions.js":"/home/senadu/projects/ribica/front-ui/app/actions/navigationActions.js","../../stores/cartStore.js":"/home/senadu/projects/ribica/front-ui/app/stores/cartStore.js","./cartTotal":"/home/senadu/projects/ribica/front-ui/app/components/cart/cartTotal.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js"}],"/home/senadu/projects/ribica/front-ui/app/components/cart/cartPage.js":[function(require,module,exports){ -var React = require('react'), - CartStore = require('../../stores/cartStore'), - AddToCart = require('../cart/addToCart'), - CartActions = require('../../actions/cartActions'), - NavigationActions = require('../../actions/navigationActions'), - SingleItem = require('../items/singleItem'), - Globals = require('../../globals'), - LinkBanner = require('../linkBanner/linkBanner'), - CartTotal = require('./cartTotal'); - AllItemsInGroup = require('../items/allItemsInGroup'); - - -var Router = require('react-router'); - -var CartPage = React.createClass({displayName: "CartPage", - _onTakeItemOut: function(itemId) { - CartActions.takeItemOut(itemId); - }, - render: function() { - var counts = this.state.itemCounts; - var self = this; - var displayedItems = this.state.items.filter(function(i) { - if(!counts) return false; - var count = counts[i.get('id')].get('count'); - return count > 0 || count === ""; - }).map(function (i) { - var count = counts[i.get('id')].get('count'); - var price = i.get('list_price'); - var firstImage = i.get('multi_media_descriptions')[0]; - firstImage = firstImage || { resized_url: "https://res.cloudinary.com/lfvt7ps2n/image/upload/c_fit,h_172,w_226/v1421732950/http_www.asms.ru_bitrix_templates_main_images_nophoto_irnofq.png" } ; - return ( - React.createElement("tr", {key: i.get('id'), className: "cart-table-row"}, - React.createElement("td", {className: "text-center"}, - React.createElement("img", {style: {maxWidth: '90px', maxHeight: '90px'}, src: firstImage.url, alt: "product image"}) - ), - React.createElement("td", null, - React.createElement("p", null, " ", i.get('brand').name), - React.createElement("p", null, - i.get('name') - ) - ), - React.createElement("td", null, Globals.FormatCurrency(price) ), - React.createElement("td", null, - React.createElement("select", {style: {textAlign: 'center'}, value: count, className: "form-control", - onChange: self._onQuantityChange.bind(self, i.get('id')) - }, - - React.createElement("option", {value: "1"}, "1"), - React.createElement("option", {value: "2"}, "2"), - React.createElement("option", {value: "3"}, "3"), - React.createElement("option", {value: "4"}, "4"), - React.createElement("option", {value: "5"}, "5"), - React.createElement("option", {value: "6"}, "6"), - React.createElement("option", {value: "7"}, "7"), - React.createElement("option", {value: "8"}, "8"), - React.createElement("option", {value: "9"}, "9"), - React.createElement("option", {value: "10"}, "10") - ) - ), - React.createElement("td", null, - Globals.FormatCurrency(count * price) - ), - React.createElement("td", null, - React.createElement("button", {className: "btn btn-default", onClick: self._onTakeItemOut.bind(self, i.get('id'))}, "Ukloni iz korpe") - ) - )) - }); - - var deliveryDestination = (React.createElement("span", null)); - - if (this.state.destinationValid) { - deliveryDestination = ( - React.createElement("div", null, - "Na adresu ", this.state.deliveryDestination.name, "," - ) - ) - } - - var cartTotal = ( - React.createElement("div", null, - React.createElement("div", {className: "row cart-total"}, - React.createElement("div", {className: "col-lg-6"}, "Ukupno"), - React.createElement("div", {className: "col-lg-6"}, - React.createElement(CartTotal, {items: this.state.items, itemCounts: this.state.itemCounts, deliveryCosts: this.state.deliveryCosts}) - ) - ), - React.createElement("div", {className: "row"}, - React.createElement("div", {className: "col-lg-12 pull-right"}, - React.createElement("button", {className: "mybutton", onClick: this._onOrderClick}, "Završi narudžbu") - ) - - ) - ) - ); - - var buySomethingMessage = (React.createElement("div", null)); - var content; - - if (displayedItems.length <= 0) { - cartTotal = (React.createElement("div", null)) - buySomethingMessage = (React.createElement("div", null, - React.createElement("div", {className: "text-primary"}, "Nemate ni jedan artikal u vašoj korpi. Kada vidite nešto što vam se sviđa - pritisnite dugme UBACI U KORPU pored artikla kako biste ga dodali u korpu."), - React.createElement("div", null, "Evo nekoliko artikala koje vam možemo preporučiti: "), - React.createElement(AllItemsInGroup, {groupId: Globals.ItemGroupIdOfEmptyCartPage}) - - )) - content = buySomethingMessage; - } else { - content = (React.createElement("div", null, - React.createElement("table", {className: "table"}, - React.createElement("thead", null, - React.createElement("tr", null, - React.createElement("th", {className: "col-lg-2"}), - React.createElement("th", null, "Proizvod"), - React.createElement("th", null, "Cijena"), - React.createElement("th", {className: "col-lg-1"}, "Količina"), - React.createElement("th", null, "Ukupna cijena"), - React.createElement("th", null) - ) - ), - React.createElement("tbody", null, - displayedItems - ) - ), - buySomethingMessage, - cartTotal - )) - } - - return ( - - React.createElement("div", {className: "col-lg-12"}, - React.createElement("div", {className: "row"}, - React.createElement("div", {className: "col-lg-12"}, - React.createElement(LinkBanner, {locationName: "checkoutPage"}) - ) - ), - React.createElement("div", {className: "row"}, - React.createElement("div", {className: "col-lg-12"}, - React.createElement("div", {className: "cart-title"}, "KORPA"), - content - ) - ) - ) - ); - - }, - - // Add change listeners to stores - componentDidMount: function() { - CartStore.addChangeListener(this._onChange); - CartActions.load(); - }, - - componentWillUnmount: function () { - CartStore.removeChangeListener(this._onChange); - }, - - _onChange: function () { - if (this.isMounted()) { - this.setState(CartStore.getWholeCartState()); - } - - }, - _onOrderClick: function () { - NavigationActions.goToCheckout(); - }, - _onQuantityChange(itemId, e) { - CartActions.setItemCount(itemId, e.target.value); - }, - getInitialState: function () { - return CartStore.getWholeCartState(); - } -}); - - -module.exports = CartPage; - - -},{"../../actions/cartActions":"/home/senadu/projects/ribica/front-ui/app/actions/cartActions.js","../../actions/navigationActions":"/home/senadu/projects/ribica/front-ui/app/actions/navigationActions.js","../../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","../../stores/cartStore":"/home/senadu/projects/ribica/front-ui/app/stores/cartStore.js","../cart/addToCart":"/home/senadu/projects/ribica/front-ui/app/components/cart/addToCart.js","../items/allItemsInGroup":"/home/senadu/projects/ribica/front-ui/app/components/items/allItemsInGroup.js","../items/singleItem":"/home/senadu/projects/ribica/front-ui/app/components/items/singleItem.js","../linkBanner/linkBanner":"/home/senadu/projects/ribica/front-ui/app/components/linkBanner/linkBanner.js","./cartTotal":"/home/senadu/projects/ribica/front-ui/app/components/cart/cartTotal.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/components/cart/cartTotal.js":[function(require,module,exports){ -var React = require('react'), - Globals = require('../../globals'); - ; - -var Router = require('react-router'); - - - -var CartTotal = React.createClass({displayName: "CartTotal", - - render: function() { - - - - var counts = this.props.itemCounts; - var total = 0; - - var items = this.props.items.models; - - for (var i = 0; i < items.length; i++) { - var item = items[i]; - var count = counts[item.get('id')].get('count'); - var price = item.get('list_price'); - total += (price * count) - }; - - - - return ( React.createElement("span", null, Globals.FormatCurrency(total))); - - } - -}); - - -module.exports = CartTotal; - - -},{"../../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/components/cart/checkoutPage.js":[function(require,module,exports){ -var React = require('react'), - CartStore = require('../../stores/cartStore'), - AddToCart = require('../cart/addToCart'), - CartActions = require('../../actions/cartActions'), - NavigationActions = require('../../actions/navigationActions'), - SingleItem = require('../items/singleItem'), - Globals = require('../../globals'), - CartTotal = require('./cartTotal'), - LinkBanner = require('../linkBanner/linkBanner'), - RibicaFormError = require('../shared/ribicaFormError'); - - -var Router = require('react-router'); - - -var CheckoutPage = React.createClass({displayName: "CheckoutPage", - - render: function() { - - var supportedPlaceOptions = CartStore.getSupportedPlaces().map ( function (p) { return (React.createElement("option", {value: p.code}, p.place))}) - - return ( -React.createElement("div", {className: "checkout-page center"}, - React.createElement("div", {className: "form-horizontal"}, - React.createElement("fieldset", null, - React.createElement("legend", null, "Dostava"), - React.createElement("div", {className: "form-group"}, - - React.createElement("label", {className: "col-md-4 control-label", htmlFor: "name"}, "Prezime i Ime"), - React.createElement("div", {className: "col-md-4"}, - React.createElement(RibicaFormError, {componentName: "name", errorMessagesObject: this.state.deliveryDestinationErrors}), - React.createElement("input", {id: "name", name: "name", type: "text", placeholder: "Prezime Ime", className: "form-control input-md", required: "", value: this.state.deliveryDestination.get('name'), onChange: this._onFieldChange}), - React.createElement("span", {className: "help-block"}, "ime osobe koja prima pošiljku") - ) - ), - React.createElement("div", {className: "form-group"}, - React.createElement("label", {className: "col-md-4 control-label", htmlFor: "name"}, "Adresa"), - React.createElement("div", {className: "col-md-4"}, - React.createElement(RibicaFormError, {componentName: "address", errorMessagesObject: this.state.deliveryDestinationErrors}), - React.createElement("input", {id: "address", name: "address", type: "text", placeholder: "Ulica i broj", className: "form-control input-md", required: "", value: this.state.deliveryDestination.get('address'), onChange: this._onFieldChange}), - React.createElement("span", {className: "help-block"}, "adresa na koju će roba biti isporučena") - ) - ), - - React.createElement("div", {className: "form-group"}, - React.createElement("label", {className: "col-md-4 control-label", htmlFor: "place"}, "Mjesto"), - React.createElement("div", {className: "col-md-4"}, - React.createElement(RibicaFormError, {componentName: "place", errorMessagesObject: this.state.deliveryDestinationErrors}), - React.createElement("select", {id: "place", name: "place", className: "form-control", value: this.state.deliveryDestination.get('place'), onChange: this._onFieldChange}, - - supportedPlaceOptions - - ) - ) - ), - React.createElement("div", {className: "form-group"}, - React.createElement("label", {className: "col-md-4 control-label", htmlFor: "phone"}, "Telefon"), - React.createElement("div", {className: "col-md-4"}, - React.createElement(RibicaFormError, {componentName: "phone", errorMessagesObject: this.state.deliveryDestinationErrors}), - React.createElement("div", {className: "input-group"}, - React.createElement("span", {className: "input-group-addon"}, "+387 "), - React.createElement("input", {id: "phone", name: "phone", className: "form-control", placeholder: "061 222 333", type: "text", required: "", value: this.state.deliveryDestination.get('phone'), onChange: this._onFieldChange}) - ), - React.createElement("p", {className: "help-block"}, "broj mobitela - mora biti sa jedne od mreža u BiH") - ) - ), - React.createElement("div", {className: "form-group"}, - React.createElement("label", {className: "col-md-4 control-label", htmlFor: "email"}, "E - mail"), - React.createElement("div", {className: "col-md-4"}, - React.createElement(RibicaFormError, {componentName: "email", errorMessagesObject: this.state.deliveryDestinationErrors}), - React.createElement("input", {id: "email", name: "email", type: "text", placeholder: "ime@nekimail.com", className: "form-control input-md", required: "", value: this.state.deliveryDestination.get('email'), onChange: this._onFieldChange}), - React.createElement("span", {className: "help-block"}, "E - mail adresa na koju će vam biti poslano obavještenje o narudžbi") - ) - ), - React.createElement("div", {className: "form-group"}, - React.createElement("label", {className: "col-md-4 control-label", htmlFor: "note"}, "Napomena"), - React.createElement("div", {className: "col-md-4"}, - React.createElement("textarea", {className: "form-control", id: "note", name: "note", value: this.state.deliveryDestination.get('note'), onChange: this._onFieldChange}) - ) - ), - React.createElement("div", {className: "form-group"}, - React.createElement("label", {className: "col-md-4 control-label", htmlFor: "order"}), - React.createElement("div", {className: "col-md-8"}, - React.createElement("div", null, "Ukupno: ", React.createElement(CartTotal, {items: this.state.items, itemCounts: this.state.itemCounts, deliveryCosts: this.state.deliveryCosts}), " "), - React.createElement("div", null, React.createElement("button", {id: "order", name: "order", className: "mybutton", disabled: !this.state.isDeliveryDestinationValid, onClick: this._onOrderClick}, "Završi narudžbu")) - ) - ) - ) -) -) - ); - - }, - - // Add change listeners to stores - componentDidMount: function() { - CartStore.addChangeListener(this._onChange); - CartActions.load(); - }, - - componentWillUnmount: function () { - CartStore.removeChangeListener(this._onChange); - }, - - _onChange: function () { - if (this.isMounted()) { - this.setState(CartStore.getWholeCartState()); - } - - }, - _onFieldChange: function (event) { - CartActions.changeDeliveryDestinationProperty(event.target.name, event.target.value); - }, - - _onOrderClick: function (event) { - CartActions.confirmDelivery(); - }, - - getInitialState: function () { - return CartStore.getWholeCartState(); - } - -}); - - -module.exports = CheckoutPage; - - -},{"../../actions/cartActions":"/home/senadu/projects/ribica/front-ui/app/actions/cartActions.js","../../actions/navigationActions":"/home/senadu/projects/ribica/front-ui/app/actions/navigationActions.js","../../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","../../stores/cartStore":"/home/senadu/projects/ribica/front-ui/app/stores/cartStore.js","../cart/addToCart":"/home/senadu/projects/ribica/front-ui/app/components/cart/addToCart.js","../items/singleItem":"/home/senadu/projects/ribica/front-ui/app/components/items/singleItem.js","../linkBanner/linkBanner":"/home/senadu/projects/ribica/front-ui/app/components/linkBanner/linkBanner.js","../shared/ribicaFormError":"/home/senadu/projects/ribica/front-ui/app/components/shared/ribicaFormError.js","./cartTotal":"/home/senadu/projects/ribica/front-ui/app/components/cart/cartTotal.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/components/items/allItems.js":[function(require,module,exports){ -var React = require('react'); -var ItemList = require('./itemList'); -var ItemStore = require('../../stores/itemStore.js'); -var ItemActions = require('../../actions/itemActions.js'); -var ItemCollection = require('../../models/itemCollection'); - -var AllItems = React.createClass({displayName: "AllItems", - - render: function() { - return ( - React.createElement(ItemList, {items: this.state.items}) - ); - }, - - // Add change listeners to stores - componentDidMount: function() { - ItemActions.loadFrontPageItems(); - ItemStore.addChangeListener(this._onChange); - }, - - - getInitialState: function() { - return { - items: ItemStore.getItems() - } - }, - - - _onChange: function () { - if (this.isMounted()) { - this.setState({ - items: ItemStore.getItems() - }); - } - }, -}); - -module.exports = AllItems; - - -},{"../../actions/itemActions.js":"/home/senadu/projects/ribica/front-ui/app/actions/itemActions.js","../../models/itemCollection":"/home/senadu/projects/ribica/front-ui/app/models/itemCollection.js","../../stores/itemStore.js":"/home/senadu/projects/ribica/front-ui/app/stores/itemStore.js","./itemList":"/home/senadu/projects/ribica/front-ui/app/components/items/itemList.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js"}],"/home/senadu/projects/ribica/front-ui/app/components/items/allItemsInGroup.js":[function(require,module,exports){ -var React = require('react'); -var ItemList = require('./itemList'); -var ItemStore = require('../../stores/itemStore.js'); -var ItemActions = require('../../actions/itemActions.js'); -var ItemCollection = require('../../models/itemCollection'); -var NavigationStore = require('../../stores/navigationStore.js'); - -var AllItemsInGroup = React.createClass({displayName: "AllItemsInGroup", - - render: function() { - return ( - React.createElement(ItemList, {items: this.state.items}) - ); - }, - - // Add change listeners to stores - componentDidMount: function() { - var groupId = this.props.groupId || NavigationStore.getGroupIdFromUrl(); - ItemActions.loadBestSellingItemsForGroup(groupId); - ItemStore.addChangeListener(this._onChange); - }, - - - componentWillUnmount: function () { - ItemStore.removeChangeListener(this._onChange); - }, - - - getInitialState: function() { - return { - items: ItemStore.getItemsForGroup() - } - }, - - - _onChange: function () { - if (this.isMounted()) { - this.setState({ - items: ItemStore.getItemsForGroup() - }); - } - }, -}); - -module.exports = AllItemsInGroup; - - -},{"../../actions/itemActions.js":"/home/senadu/projects/ribica/front-ui/app/actions/itemActions.js","../../models/itemCollection":"/home/senadu/projects/ribica/front-ui/app/models/itemCollection.js","../../stores/itemStore.js":"/home/senadu/projects/ribica/front-ui/app/stores/itemStore.js","../../stores/navigationStore.js":"/home/senadu/projects/ribica/front-ui/app/stores/navigationStore.js","./itemList":"/home/senadu/projects/ribica/front-ui/app/components/items/itemList.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js"}],"/home/senadu/projects/ribica/front-ui/app/components/items/itemGroupPage.js":[function(require,module,exports){ -var React = require('react'), - Router = require('react-router'), - RouteHandler = Router.RouteHandler, - AllItemsInGroup = require('../items/allItemsInGroup'); - -var ItemGroupPage = React.createClass({displayName: "ItemGroupPage", - render : function() { - return ( - React.createElement("div", null, - - React.createElement("div", {className: "col-md-2"} - - ), - React.createElement("div", {className: "col-md-10"}, - React.createElement(AllItemsInGroup, null) - ) - ) - ) - } -}); - -module.exports = ItemGroupPage; - - -},{"../items/allItemsInGroup":"/home/senadu/projects/ribica/front-ui/app/components/items/allItemsInGroup.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/components/items/itemList.js":[function(require,module,exports){ -var React = require('react'); -var SingleItem = require('./singleItem'); -var ItemCollection = require('../../models/itemCollection.js'); - -var ItemList = React.createClass({displayName: "ItemList", - changePage: function(page, e) { - e.preventDefault(); - if(this.props.onPageChange) { - this.props.onPageChange(page); - } - }, - render: function() { - - var items = this.props.items.models.map( function(item) { - return ( - React.createElement(SingleItem, {item: item, key: item.id}) - ); - }); - - return ( - React.createElement("div", {className: "row-fluid"}, - React.createElement("div", {className: "span10"}, - React.createElement("div", {style: {marginTop: 35, padding: '0 25px'}, className: "row"}, - items - ), - this.getPages() - ) - ) - ); - }, - getPages: function() { - if (!this.props.paginationEnabled) { - return ""; - } - - var nrOfPages = Math.ceil(this.props.total/ this.props.limit); - if (nrOfPages === 1) { - return ""; - } - - var maxSlots = 10; - var selectedIndex = Math.floor(this.props.currentOffset / this.props.limit); - - var start, end; - start = selectedIndex - Math.floor(maxSlots / 2); - end = selectedIndex + Math.floor(maxSlots / 2 ) + 1; - - if (start < 0) start = 0; - if (end > nrOfPages) end = nrOfPages; - - if ((end - start) < maxSlots) { - start = Math.max(0, end - maxSlots); - end = Math.min(nrOfPages, start + maxSlots); - } - - var pages = []; - for(var i = start; i < end; i++) { - var cn = i === selectedIndex ? "active": ""; - pages.push(React.createElement("li", {className: cn}, React.createElement("a", {onClick: this.changePage.bind(this, i), href: "#"}, i + 1))) - } - - return ( - React.createElement("nav", null, - - React.createElement("ul", {className: "pagination"}, - pages - ) - )) - } - -}); - - -module.exports = ItemList; - - -},{"../../models/itemCollection.js":"/home/senadu/projects/ribica/front-ui/app/models/itemCollection.js","./singleItem":"/home/senadu/projects/ribica/front-ui/app/components/items/singleItem.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js"}],"/home/senadu/projects/ribica/front-ui/app/components/items/itemWithDetailsPage.js":[function(require,module,exports){ -var React = require('react'), - Carousel = require('../shared/carousel'), - Traits = require('../items/traits'), - ItemDetailsActions = require('../../actions/itemDetailsActions'), - NavigationStore = require('../../stores/navigationStore'), - ItemDetailsStore = require('../../stores/itemDetailsStore'), - AddToCart = require('../cart/addToCart'); - -var Router = require('react-router'); -var Globals = require('../../globals'); - - -var ItemWithDetailsPage = React.createClass({displayName: "ItemWithDetailsPage", - - render: function() { - - return ( - - React.createElement("div", {className: "item-with-details row-fluid center"}, - React.createElement("div", {className: "col-md-5 col-md-offset-2 item_image"}, - React.createElement("img", {src: this.state.firstImage, width: "100%"}) - ), - - React.createElement("div", {className: "col-md-5"}, - React.createElement("div", {className: "item_brand_name"}, " ", this.state.item.get('brand').name), - React.createElement("div", {className: "item_name"}, " ", this.state.item.get('name')), - React.createElement("div", null, - React.createElement("div", {className: "item_price"}, " ", Globals.FormatCurrency(this.state.item.get('list_price'))), - - React.createElement("div", null, "Količina"), - - React.createElement("div", null, " ", React.createElement(AddToCart, {item: this.state.item})), - - React.createElement("div", null, - React.createElement("div", {className: "item_description_tab"}, "Opis proizvoda"), - React.createElement("div", {className: "item_description_tab_area"}, " "), - React.createElement("div", {className: "item_description_text"}, this.state.item.get('description')) - ) - ), - - React.createElement(Traits, {traits: this.state.item.get('traits')}) - - ) - ) - ); - - }, - - // Add change listeners to stores - componentDidMount: function() { - ItemDetailsStore.addChangeListener(this._onChange); - NavigationStore.addChangeListener(this._onChange); - ItemDetailsActions.loadItemWithDetails(); - }, - - componentWillUnmount: function () { - ItemDetailsStore.removeChangeListener(this._onChange); - NavigationStore.removeChangeListener(this._onChange); - }, - - - onClickLeft: function() { - ItemDetailsActions.previousCarouselImage(); - - }, - - onClickRight: function() { - ItemDetailsActions.nextCarouselImage(); - }, - - onSelectImage: function(i) { - ItemDetailsActions.selectCarouselImage(i); - }, - - _onChange: function () { - - if (this.isMounted()) { - this.setState(ItemDetailsStore.getState()); - } - - }, - - getInitialState: function () { - return ItemDetailsStore.getState(); - } - -}); - - -module.exports = ItemWithDetailsPage; - - -},{"../../actions/itemDetailsActions":"/home/senadu/projects/ribica/front-ui/app/actions/itemDetailsActions.js","../../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","../../stores/itemDetailsStore":"/home/senadu/projects/ribica/front-ui/app/stores/itemDetailsStore.js","../../stores/navigationStore":"/home/senadu/projects/ribica/front-ui/app/stores/navigationStore.js","../cart/addToCart":"/home/senadu/projects/ribica/front-ui/app/components/cart/addToCart.js","../items/traits":"/home/senadu/projects/ribica/front-ui/app/components/items/traits.js","../shared/carousel":"/home/senadu/projects/ribica/front-ui/app/components/shared/carousel.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/components/items/singleItem.js":[function(require,module,exports){ -var React = require('react'); -var ItemActions = require('../../actions/itemActions'); -var NavigationActions = require('../../actions/navigationActions'); -var NavigationStore = require('../../stores/navigationStore'); - -var Globals = require('../../globals'); -var Router = require('react-router'); - -var SingleItem = React.createClass({displayName: "SingleItem", - render: function() { - var hidePrice = this.props.hidePrice || false; - var self = this; - var itemClick = this.itemClick; - var firstImage = this.props.item.get('multi_media_descriptions')[0]; - firstImage = firstImage || { resized_url: "https://res.cloudinary.com/lfvt7ps2n/image/upload/c_fit,h_172,w_226/v1421732950/http_www.asms.ru_bitrix_templates_main_images_nophoto_irnofq.png" } ; - if (hidePrice) { - return ( - React.createElement("div", {className: "col-lg-2 col-md-2 col-sm-3 col-xs-6"}, - React.createElement("div", {className: "productbox"}, - React.createElement("img", {className: "img-responsive", src: firstImage.url, alt: "product image"}), - React.createElement("div", null, - - React.createElement("p", null, " ", React.createElement("p", {className: "productbox item_brand_name"}, this.props.item.get('brand') ? this.props.item.get('brand').name : ''), this.props.item.get('name') ) - - ) - ) - ) - ); - } - else { - return ( - - React.createElement("div", {className: "col-lg-3 col-md-3 col-sm-4 col-xs-6", onClick: itemClick}, - React.createElement("div", {className: "productbox"}, - React.createElement("img", {className: "img-responsive", src: firstImage.resized_url, alt: "product image"}), - React.createElement("div", {style: {height: "90px"}, className: "item_name_and_price"}, - React.createElement("p", null, React.createElement("span", {className: "text-uppercase"}, this.props.item.get('brand') ? this.props.item.get('brand').name : ''), - React.createElement("br", null), React.createElement("span", {className: "text-capitalize"}, this.props.item.get('name') )), - React.createElement("h4", {className: "item_floating_price"}, Globals.FormatCurrency(this.props.item.get('list_price')) ) - ) - ) - ) - ); - } - }, - - itemClick: function(e) { - NavigationActions.goToItemDetails(this.props.item); - - } -}); - - -module.exports = SingleItem; - - -},{"../../actions/itemActions":"/home/senadu/projects/ribica/front-ui/app/actions/itemActions.js","../../actions/navigationActions":"/home/senadu/projects/ribica/front-ui/app/actions/navigationActions.js","../../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","../../stores/navigationStore":"/home/senadu/projects/ribica/front-ui/app/stores/navigationStore.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/components/items/traits.js":[function(require,module,exports){ -var React = require('react'); - -var Traits = React.createClass({displayName: "Traits", - render: function() { - - var traitsPresentation = []; - var traits = (this.props.traits || {}); - for(var traitKey in traits ) { - if(traits.hasOwnProperty(traitKey)) { - var traitValue = this.props.traits[traitKey]; - traitsPresentation.push( React.createElement("div", {key: traitKey, className: "single_trait"}, traitKey, ": ", traitValue) ); - } - } - - - return ( - React.createElement("div", {className: "row-fluid"}, - React.createElement("div", {className: "span12"}, - traitsPresentation - ) - ) - ); - } -}); - - -module.exports = Traits; - - -},{"react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js"}],"/home/senadu/projects/ribica/front-ui/app/components/linkBanner/linkBanner.js":[function(require,module,exports){ -var React = require('react'); -var ItemActions = require('../../actions/itemActions'); -var NavigationActions = require('../../actions/navigationActions'); -var InitializationStore = require('../../stores/initializationStore') - -var Router = require('react-router'); - -var LinkBanner = React.createClass({displayName: "LinkBanner", - propTypes: { - locationName: React.PropTypes.string.isRequired, - locationId: React.PropTypes.number, - }, - - - render: function() { - - var banners = this.state.banners.map(function (banner) { - - return React.createElement("div", {key: "banner" + banner.get('id')}, React.createElement("a", {href: banner.get('link_url')}, React.createElement("img", {className: "img-responsive center-block", src: banner.get('image_url')}))) - - }); - - return (React.createElement("div", null, banners )); - - }, - getInitialState: function () { - - - var allBanners = InitializationStore.getBanners(); - var locationId = this.props.locationId; - var locationName = this.props.locationName; - var bannersToShow = []; - - if (locationId) { - bannersToShow = allBanners[locationName][locationId]; - - } else { - bannersToShow = allBanners[locationName]; - - } - - bannersToShow = bannersToShow || []; - - - return { banners: bannersToShow }; - } - -}); - - -module.exports = LinkBanner; - - -},{"../../actions/itemActions":"/home/senadu/projects/ribica/front-ui/app/actions/itemActions.js","../../actions/navigationActions":"/home/senadu/projects/ribica/front-ui/app/actions/navigationActions.js","../../stores/initializationStore":"/home/senadu/projects/ribica/front-ui/app/stores/initializationStore.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/components/rootApp.js":[function(require,module,exports){ -var React = require('react'), - MenuItemListComponent = require('./shared/menuItemListComponent'), - SectionListComponent = require('./shared/sectionsListComponent'), - - Router = require('react-router'), - Link = Router.Link, - RouteHandler = Router.RouteHandler, - LoginStatus = require('./shared/loginStatus'), - InitializationStore = require('../stores/initializationStore'), - NavigationStore = require('../stores/navigationStore'), - InitializationActions = require('../actions/initializationActions'); - -var CartIcon = require('./cart/cartIcon'); -var SearchBox = require('./shared/searchBox'); - -var RootApp = React.createClass({displayName: "RootApp", - - // Add change listeners to stores - componentDidMount: function() { - InitializationStore.addChangeListener(this._onChange); - InitializationActions.initialize(); - }, - - - getInitialState: function() { - return InitializationStore.getState(); - }, - - - _onChange: function () { - if (this.isMounted()) { - this.setState(InitializationStore.getState()); - } - }, - - componentWillUnmount: function () { - InitializationStore.removeChangeListener(this._onChange); - }, - - shouldShowCart: function () { - return !NavigationStore.hideCart(); - }, - - render: function() { - - if (!this.state.isEverythingReadyToStartTheShow) { - return (React.createElement("div", null, "loading...")); - } - - var cart = ""; - - if(this.shouldShowCart()) { - cart = (React.createElement(CartIcon, null)); - } - - return ( -React.createElement("div", {className: "container"}, - React.createElement("div", null, - React.createElement("div", {className: "col-lg-12 hidden-sm hidden-xs ", style: {height: 80, background: 'none', marginBottom: '0px !important'}, id: "mybody"}, - - React.createElement("div", {style: {padding: '15px 15px'}, className: "col-lg-2 col-md-2 col-sm-2 col-xs-2"}, - React.createElement(Link, {to: "app"}, React.createElement("img", {height: 50, src: "https://res.cloudinary.com/du5pdibul/image/upload/v1428813560/logo_h5f9yp.png"})) - ), - - React.createElement("div", {style: {padding: '30px 15px'}, className: "col-lg-6 col-md-6 col-sm-6 col-xs-6"}, - React.createElement(SearchBox, null) - ), - - React.createElement("div", {style: {padding: '15px 15px'}, className: "col-lg-4 col-md-4 hidden-sm hidden-xs"}, - React.createElement("nav", {style: {background: 'none', border: 'none', marginBottom: '0px !important'}, className: "navbar mytopnav"}, - React.createElement("div", null, - cart - ) - ) - ) - ), - React.createElement("div", {style: {margin: '0 !important'}, className: "clearfix"} - ) - ), - React.createElement("div", null, - React.createElement(MenuItemListComponent, null) - ), - - React.createElement("div", {className: "row"}, - React.createElement(RouteHandler, null) - ) -) -); - - - - } -}); - -module.exports = RootApp; - - -},{"../actions/initializationActions":"/home/senadu/projects/ribica/front-ui/app/actions/initializationActions.js","../stores/initializationStore":"/home/senadu/projects/ribica/front-ui/app/stores/initializationStore.js","../stores/navigationStore":"/home/senadu/projects/ribica/front-ui/app/stores/navigationStore.js","./cart/cartIcon":"/home/senadu/projects/ribica/front-ui/app/components/cart/cartIcon.js","./shared/loginStatus":"/home/senadu/projects/ribica/front-ui/app/components/shared/loginStatus.js","./shared/menuItemListComponent":"/home/senadu/projects/ribica/front-ui/app/components/shared/menuItemListComponent.js","./shared/searchBox":"/home/senadu/projects/ribica/front-ui/app/components/shared/searchBox.js","./shared/sectionsListComponent":"/home/senadu/projects/ribica/front-ui/app/components/shared/sectionsListComponent.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/components/search/searchResultsPage.js":[function(require,module,exports){ -var React = require('react'), - NavigationActions = require('../../actions/navigationActions'), - Globals = require('../../globals') - Router = require("react-router"), - LinkBanner = require('../linkBanner/linkBanner'), - Link = Router.Link; - -var SearchStore = require('../../stores/searchStore'); -var SearchActions = require('../../actions/searchActions'); - -var ItemList = require('../items/itemList'); -var SearchResultsPage = React.createClass({displayName: "SearchResultsPage", - mixins: [Router.State], - getInitialState: function() { - return SearchStore.getSearchResultsState(); - }, - render: function() { - var content; - - if (this.state.items.length > 0) { - content = React.createElement(ItemList, {items: this.state.items}) - } else { - - content = React.createElement("div", null, "Nema rezultata za vašu pretragu.") - } - return ( - React.createElement("div", null, - - React.createElement(LinkBanner, {locationName: "searchResultPage"}), - React.createElement("h2", null, "Rezultati pretrage za '", this.state.q, "'"), - - content - ) - ); - }, - componentWillReceiveProps: function() { - this.update(); - }, - update: function(){ - var query = this.getQuery(); - SearchActions.getSearchResults(query.q); - }, - componentDidMount: function() { - SearchStore.addChangeListener(this._onChange); - this.update(); - - //CartActions.load(); - }, - componentWillUnmount: function () { - SearchStore.removeChangeListener(this._onChange); - }, - _onChange: function() { - if(this.isMounted()) { - this.setState(SearchStore.getSearchResultsState()); - } - } -}); - - -module.exports = SearchResultsPage; - - -},{"../../actions/navigationActions":"/home/senadu/projects/ribica/front-ui/app/actions/navigationActions.js","../../actions/searchActions":"/home/senadu/projects/ribica/front-ui/app/actions/searchActions.js","../../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","../../stores/searchStore":"/home/senadu/projects/ribica/front-ui/app/stores/searchStore.js","../items/itemList":"/home/senadu/projects/ribica/front-ui/app/components/items/itemList.js","../linkBanner/linkBanner":"/home/senadu/projects/ribica/front-ui/app/components/linkBanner/linkBanner.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/components/shared/carousel.js":[function(require,module,exports){ -var React = require("react"); - -var Carousel = React.createClass({displayName: "Carousel", - propTypes: { - images: React.PropTypes.array.isRequired, - selected: React.PropTypes.number.isRequired, - onClickLeft: React.PropTypes.func.isRequired, - onClickRight: React.PropTypes.func.isRequired, - onSelectImage: React.PropTypes.func.isRequired - }, - - render: function() { - var left = this.props.selected * 300 * -1, - ulStyle = { - width: this.props.images.length * 300, - "-ms-transform": "translate(" + left + "px,0px)", - "-webkit-transform": "translate(" + left + "px,0px)", - transform: "translate(" + left + "px,0px)" - }; - - return ( - React.createElement("div", null, - React.createElement("span", {className: "arrow left", - onClick: this.props.onClickLeft}, "◄"), - React.createElement("div", {className: "carousel-stage"}, - React.createElement("ul", {style: ulStyle, className: "carousel-list"}, - this.props.images.map(function(image, i) { - return React.createElement("li", {key: i}, React.createElement("img", {src: image})); - }) - ), - React.createElement("ul", {className: "dots"}, - this.props.images.map(function(image, i) { - var activeClass = i === this.props.selected ? "active" : ""; - return React.createElement("li", {key: i, - className: "circle " + activeClass, - onClick: this.onClickDot.bind(this, i)}); - }.bind(this)) - ) - ), - React.createElement("span", {className: "arrow right", - onClick: this.props.onClickRight}, "►") - ) - ) - }, - - onClickDot: function(index) { - this.props.onSelectImage(index); - } -}); - -module.exports = Carousel; - -},{"react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js"}],"/home/senadu/projects/ribica/front-ui/app/components/shared/loginStatus.js":[function(require,module,exports){ -var React = require("react"), - Router = require("react-router"), - Link = Router.Link; - -var UserStore = require('../../stores/userStore'); -var UserActions = require('../../actions/userActions'); - -var LoginStatus = React.createClass({displayName: "LoginStatus", - getInitialState: function() { - return UserStore.getLoginState(); - }, - componentDidMount: function() { - UserStore.addChangeListener(this.onUserStateChange); - UserActions.checkLogin(); - }, - componentWillReceiveProps: function() { - this.update(); - }, - componentWillUnmount: function() { - UserStore.removeChangeListener(this.onUserStateChange); - }, - onUserStateChange: function() { - this.update(); - }, - update: function() { - if(this.isMounted()) { - this.setState(UserStore.getLoginState()); - } - }, - logout: function(e){ - e.preventDefault(); - UserActions.userLogout(); - }, - render : function() { - - - var content; - - if(this.state.loggedIn){ - content = (React.createElement("div", {style: {display: 'inline-block', paddingTop: '18px', paddingRight: '10px'}}, this.state.user.first_name, " ", this.state.user.last_name, " ", React.createElement("a", {onClick: this.logout, style: { paddingLeft: '10px'}}, "Odjavite se"))) - } else { - content = (React.createElement("div", {style: {display: 'inline-block', paddingTop: '18px', paddingRight: '10px'}}, React.createElement(Link, {to: "registracija", style: { paddingRight: '10px'}}, "Registracija"), " ", React.createElement(Link, {to: "login"}, "Prijava"))) - } - - return content; - } -}) -module.exports = LoginStatus; - - -},{"../../actions/userActions":"/home/senadu/projects/ribica/front-ui/app/actions/userActions.js","../../stores/userStore":"/home/senadu/projects/ribica/front-ui/app/stores/userStore.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/components/shared/menuItemListComponent.js":[function(require,module,exports){ -var React = require('react'), - MenuItemCollection = require('../../models/menuItemCollection'), - MenuItem = require('../../models/menuItem'), - Backbone = require('backbone'), - NavigationStore = require('../../stores/navigationStore'), - MenuItemStore = require('../../stores/menuItemStore'), - CartStore = require('../../stores/cartStore.js'); - MenuItemActions = require('../../actions/menuItemActions'), - NavigationActions = require('../../actions/navigationActions'); - -Backbone.$ = $; - -var MenuItemListComponent = React.createClass({displayName: "MenuItemListComponent", - - _onChange: function () { - if (this.isMounted()) { - this.setState(MenuItemStore.getState()); - } - }, - - getInitialState: function() { - var state = MenuItemStore.getState(); - var cartState = CartStore.getWholeCartState(); - state.cartCount = cartState; - return state; - }, - - componentDidMount: function() { - MenuItemStore.addChangeListener(this._onChange); - MenuItemActions.loadMenuItems(); - }, - onMouseOver: function(menuItem) { - MenuItemActions.setMenuItemHover(menuItem); - }, - onMouseOut: function() { - MenuItemActions.unsetMenuItemHover(); - }, - onMouseLeave: function() { - MenuItemActions.unsetMenuItemHover(); - }, - onMenuItemClick: function(menuItem, e) { - MenuItemActions.unsetMenuItemHover(); - NavigationActions.goToMenuItem(menuItem); - e.preventDefault(); - }, - _onCartClick: function(e) { - NavigationActions.goToCart(); - e.preventDefault(); - }, - - render: function() { - var self = this; - var style = { - position: 'relative' - }; - var abStyle = { - position: 'absolute' - }; - return ( - React.createElement("div", {className: "navbar navbar-default navbar-static-top"}, - React.createElement("div", {className: "container"}, - React.createElement("ul", {className: "nav nav-pills"}, - React.createElement("div", {className: "navbar-header"}, - React.createElement("button", {type: "button", className: "navbar-toggle", "data-toggle": "collapse", "data-target": ".navbar-collapse"}, - React.createElement("span", {className: "icon-bar"}), - React.createElement("span", {className: "icon-bar"}), - React.createElement("span", {className: "icon-bar"}) - ), - React.createElement("a", {className: "navbar-brand hidden-lg hidden-md", href: "#"}, React.createElement("img", {style: {marginTop: '-4px'}, height: 24, src: "https://res.cloudinary.com/du5pdibul/image/upload/v1428813560/logo_h5f9yp.png"})), - React.createElement("ul", {className: "mynav hidden-lg hidden-md ", style: {listStyle: 'none'}}, - React.createElement("li", null, React.createElement("a", {href: "#"}, "0,00 KM")), - React.createElement("li", {onClick: this._onCartClick}, React.createElement("a", {style: {marginLeft: 10}, className: "mybutton", href: "#", onClick: this._onCartClick}, "Završi narudžbu")) - ) - ), - React.createElement("div", {className: "navbar-collapse collapse"}, - React.createElement("ul", {className: "nav navbar-nav hidden-sm hidden-xs "}, - /* -
  • Današnja ponuda
  • -
  • - Beba - -
  • */ - - this.state.menuItems.map(function(menuItem) { - return React.createElement("li", {className: "mydropdown menu-large", onMouseLeave: self.onMouseOut, onMouseOver: self.onMouseOver.bind(self, menuItem)}, - React.createElement("a", {href: "#", className: "dropdown-toggle ", id: menuItem.get('title').toLowerCase(), onClick: self.onMenuItemClick.bind(self, menuItem)}, menuItem.get('title')), - React.createElement("ul", {className: menuItem.get('id') !== self.state.hoveredMenuItem ? "dropdown-menu megamenu row hide": "dropdown-menu megamenu row"}, - menuItem.get('menu_sub_items').map(function(menuSubItem) { - return ( - React.createElement("li", {className: "col-sm-3", key: menuSubItem.id}, - - React.createElement("ul", null, - React.createElement("li", {className: "dropdown-header"}, React.createElement("a", {href: "#", onClick: self.onMenuItemClick.bind(self, menuSubItem)}, React.createElement("p", null, menuSubItem.title))), - menuSubItem.menu_sub_sub_items.map(function(menuSubSubItem) { - return (React.createElement("li", null, React.createElement("a", {href: "#", onClick: self.onMenuItemClick.bind(self, menuSubSubItem)}, menuSubSubItem.title))) - }) - ) - ) - ) - }) - ) - ) - }) - ), - React.createElement("ul", {className: "nav navbar-nav hidden-lg hidden-md "}, - /* -
  • Današnja ponuda
  • -
  • - - -
  • -
  • Dijete
  • -
  • Mama
  • -
  • Made in BiH
  • -
  • Tržišna marka
  • - - */ - this.state.menuItems.map(function(menuItem) { - return React.createElement("li", {className: "dropdown menu-large"}, - React.createElement("a", {href: "#", className: "dropdown-toggle ", "data-toggle": "dropdown", role: "button", "aria-expanded": "false"}, - menuItem.get('title'), " ", React.createElement("b", {className: "caret"}), " "), - React.createElement("ul", {className: "dropdown-menu megamenu row"}, - - menuItem.get('menu_sub_items').map(function(menuSubItem) { - return ( - React.createElement("li", {className: "col-sm-3", key: menuSubItem.id}, - - React.createElement("ul", null, - React.createElement("li", {className: "dropdown-header"}, React.createElement("a", {href: "#", onClick: self.onMenuItemClick.bind(self, menuSubItem)}, React.createElement("p", null, menuSubItem.title))), - menuSubItem.menu_sub_sub_items.map(function(menuSubSubItem) { - return (React.createElement("li", null, React.createElement("a", {href: "#", onClick: self.onMenuItemClick.bind(self, menuSubSubItem)}, menuSubSubItem.title))) - }) - ) - ) - ) - }) - ) - ) - }) - ) - ) - ) - ) - ) - ); - } -}); - -module.exports = MenuItemListComponent; - - -},{"../../actions/menuItemActions":"/home/senadu/projects/ribica/front-ui/app/actions/menuItemActions.js","../../actions/navigationActions":"/home/senadu/projects/ribica/front-ui/app/actions/navigationActions.js","../../models/menuItem":"/home/senadu/projects/ribica/front-ui/app/models/menuItem.js","../../models/menuItemCollection":"/home/senadu/projects/ribica/front-ui/app/models/menuItemCollection.js","../../stores/cartStore.js":"/home/senadu/projects/ribica/front-ui/app/stores/cartStore.js","../../stores/menuItemStore":"/home/senadu/projects/ribica/front-ui/app/stores/menuItemStore.js","../../stores/navigationStore":"/home/senadu/projects/ribica/front-ui/app/stores/navigationStore.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js"}],"/home/senadu/projects/ribica/front-ui/app/components/shared/ribicaFormError.js":[function(require,module,exports){ -var React = require('react'); - - -var RibicaFormError = React.createClass({displayName: "RibicaFormError", - render: function() { - var errorMessages = this.props.errorMessagesObject || {}; - var componentName = this.props.componentName; - var message = errorMessages[componentName]; - if (message !== undefined && message !== null && message !== "") { - return(React.createElement("div", {className: "error-message"}, message)) - } - else return (React.createElement("span", null)); - } -}); - - -module.exports = RibicaFormError; - - -},{"react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js"}],"/home/senadu/projects/ribica/front-ui/app/components/shared/searchBox.js":[function(require,module,exports){ -var React = require('react'), - Router = require('react-router'); - -var NavigationActions = require('../../actions/navigationActions'); -var SearchActions = require('../../actions/searchActions'); -var SearchStore = require('../../stores/searchStore'); - -var SearchBox = React.createClass({displayName: "SearchBox", - getInitialState: function() { - return SearchStore.getSearchBoxState(); - }, - onSearchClick: function(e) { - this.doSearch(); - e.preventDefault(); - }, - componentDidMount: function() { - SearchStore.addChangeListener(this.onSearchStoreChange); - }, - componentWillUnmount: function() { - SearchStore.removeChangeListener(this.onSearchStoreChange); - }, - onSearchStoreChange: function() { - if(this.isMounted()) { - this.setState(SearchStore.getSearchBoxState()); - } - }, - onSearchBoxChange: function(e) { - SearchActions.searchBoxChange(e.currentTarget.value); - }, - doSearch: function() { - if(this.state.q.trim() !== '') { - NavigationActions.goToSearchResults(this.state.q); - } - }, - onKeyPress: function(e) { - var enterKeyCode = 13; - if(e.which == enterKeyCode) { - this.doSearch(); - e.preventDefault(); - } - }, - render: function() { - return (React.createElement("form", {style: {marginLeft: '60px', width: '100%'}, className: "form-inline"}, - React.createElement("div", {className: "left-inner-addon"}, - React.createElement("i", {className: "glyphicon glyphicon-search"}), - React.createElement("input", {style: {width: '75%'}, type: "search", onKeyPress: this.onKeyPress, - className: "search-box form-control", - value: this.state.q, onChange: this.onSearchBoxChange, - "aria-hidden": "true"} - - ), - - React.createElement("button", {className: "btn btn-default search-button", type: "button", - onClick: this.onSearchClick}, "Traži") - - ) - )) - } -}); - -module.exports = SearchBox; - - -},{"../../actions/navigationActions":"/home/senadu/projects/ribica/front-ui/app/actions/navigationActions.js","../../actions/searchActions":"/home/senadu/projects/ribica/front-ui/app/actions/searchActions.js","../../stores/searchStore":"/home/senadu/projects/ribica/front-ui/app/stores/searchStore.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/components/shared/sectionsListComponent.js":[function(require,module,exports){ -var React = require('react'), - SectionCollection = require('../../models/sectionCollection'), - Section = require('../../models/section'), - Category = require('../../models/category'), - Backbone = require('backbone'), - NavigationStore = require('../../stores/navigationStore'), - SectionStore = require('../../stores/sectionStore'), - SectionActions = require('../../actions/sectionActions'), - NavigationActions = require('../../actions/navigationActions'); - -Backbone.$ = $; - -var SectionsListComponent = React.createClass({displayName: "SectionsListComponent", - - _onChange: function () { - if (this.isMounted()) { - this.setState(SectionStore.getState()); - } - }, - - getInitialState: function() { - return SectionStore.getState(); - }, - - componentDidMount: function() { - SectionStore.addChangeListener(this._onChange); - SectionActions.loadSections(); - }, - onMouseOver: function(section) { - SectionActions.setSectionHover(section); - - }, - onMouseOut: function() { - SectionActions.unsetSectionHover(); - }, - onMouseLeave: function() { - SectionActions.unsetSectionHover(); - }, - onSectionClick: function(section) { - SectionActions.unsetSectionHover(); - NavigationActions.goToSection(section); - event.preventDefault(); - }, - onCategoryClick: function(category, section) { - SectionActions.unsetSectionHover(); - NavigationActions.goToCategory(new Category(category), section); - event.preventDefault(); - }, - onSubcategoryClick: function(subcategory) { - // implement in navigation actions - // and call - // when ready - return false; - }, - render: function() { - var self = this; - var style = { - position: 'relative' - }; - var abStyle = { - position: 'absolute' - }; - return ( - React.createElement("div", null, - React.createElement("ul", {className: "nav nav-pills"}, - this.state.sections.map(function(section) { - - return ( - React.createElement("li", {key: section.get('id'), onMouseLeave: self.onMouseOut, onMouseOver: self.onMouseOver.bind(self, section), role: "presentation", style: style}, - React.createElement("a", {href: "#", onClick: self.onSectionClick.bind(self, section)}, - section.get('name') - - ), - React.createElement("div", {style: abStyle, className: section.get('id') !== self.state.hoveredSection ? "hide section-cat-list": "section-cat-list"}, - - React.createElement("ul", null, - section.get('categories').map(function(category) { - return ( - React.createElement("li", {key: category.id}, - React.createElement("a", {onClick: self.onCategoryClick.bind(self, category, section)}, category.name) - ) - ) - }) - ) - ) - ) - ) - }) - ) - ) - ); - } -}); - -module.exports = SectionsListComponent; - - -},{"../../actions/navigationActions":"/home/senadu/projects/ribica/front-ui/app/actions/navigationActions.js","../../actions/sectionActions":"/home/senadu/projects/ribica/front-ui/app/actions/sectionActions.js","../../models/category":"/home/senadu/projects/ribica/front-ui/app/models/category.js","../../models/section":"/home/senadu/projects/ribica/front-ui/app/models/section.js","../../models/sectionCollection":"/home/senadu/projects/ribica/front-ui/app/models/sectionCollection.js","../../stores/navigationStore":"/home/senadu/projects/ribica/front-ui/app/stores/navigationStore.js","../../stores/sectionStore":"/home/senadu/projects/ribica/front-ui/app/stores/sectionStore.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js"}],"/home/senadu/projects/ribica/front-ui/app/components/startPage/startPage.js":[function(require,module,exports){ -var React = require('react'), - Router = require('react-router'), - RouteHandler = Router.RouteHandler, - AllItems = require('../items/allItems'), - LinkBanner = require('../linkBanner/linkBanner'), - AllItemsInGroup = require('../items/allItemsInGroup'); - -var StartPage = React.createClass({displayName: "StartPage", - render : function() { - return ( - React.createElement("div", null, - - React.createElement("div", {className: "col-md-12"}, - React.createElement(LinkBanner, {locationName: "startPage"}), - React.createElement(AllItemsInGroup, null), - React.createElement(RouteHandler, null) - ) - ) - ) - } -}); - -module.exports = StartPage; - - -},{"../items/allItems":"/home/senadu/projects/ribica/front-ui/app/components/items/allItems.js","../items/allItemsInGroup":"/home/senadu/projects/ribica/front-ui/app/components/items/allItemsInGroup.js","../linkBanner/linkBanner":"/home/senadu/projects/ribica/front-ui/app/components/linkBanner/linkBanner.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/components/thankyou/thankYouPage.js":[function(require,module,exports){ -var React = require('react'), - CartStore = require('../../stores/cartStore'), - AddToCart = require('../cart/addToCart'), - CartActions = require('../../actions/cartActions'), - LinkBanner = require('../linkBanner/linkBanner'), - NavigationActions = require('../../actions/navigationActions'), - Globals = require('../../globals') - Router = require("react-router"), - Link = Router.Link; - - -var ThankYouPage = React.createClass({displayName: "ThankYouPage", - - render: function() { - - return ( - - React.createElement("div", {className: "thank-you-page center"}, - React.createElement("h1", null, "Roba je naručena!"), - React.createElement("p", null, "Hvala na narudžbi. Naša zaposlenica će vas kontaktirati da ugovori detalje o preuzimanju. "), - - React.createElement("p", null, React.createElement(LinkBanner, {locationName: "thankYouPage"})) - - /* -

    Registrujte se kako biste dobili informaciju o popustima, imali pregled svih vaših narudžbi, - koristili Baby Shower, Predlagač poklona te kalendar događaja.

    - -

    - Registracija je jednostavna - samo jedan klik. Klikni ovdje. -

    - */ - ) - - ); - - } - -}); - - -module.exports = ThankYouPage; - - -},{"../../actions/cartActions":"/home/senadu/projects/ribica/front-ui/app/actions/cartActions.js","../../actions/navigationActions":"/home/senadu/projects/ribica/front-ui/app/actions/navigationActions.js","../../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","../../stores/cartStore":"/home/senadu/projects/ribica/front-ui/app/stores/cartStore.js","../cart/addToCart":"/home/senadu/projects/ribica/front-ui/app/components/cart/addToCart.js","../linkBanner/linkBanner":"/home/senadu/projects/ribica/front-ui/app/components/linkBanner/linkBanner.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/constants/bySubCategoryConstants.js":[function(require,module,exports){ -var keyMirror = require('react/lib/keyMirror'); - -// Define action constants -module.exports = keyMirror({ - LOAD: null, - FILTER_CRITERIA_CLICK: null, - REMOVE_APPLIED_FILTER: null, - CHANGE_PAGE: null -}); - - -},{"react/lib/keyMirror":"/home/senadu/projects/ribica/front-ui/node_modules/react/lib/keyMirror.js"}],"/home/senadu/projects/ribica/front-ui/app/constants/cartConstants.js":[function(require,module,exports){ -var keyMirror = require('react/lib/keyMirror'); - -// Define action constants -module.exports = keyMirror({ - LOAD_CART_CONTENTS: null, - CART_DATA_LOADED: null, - SAVE_CART_STATE_FOR_ITEM: null, - CHANGE_DELIVERY_DESTINATION_PROPERTY: null, - CONFIRM_DELIVERY: null, - SET_ITEM_COUNT: null, - ADD_N_ITEMS: null, - REMOVE_ITEM: null -}); - - -},{"react/lib/keyMirror":"/home/senadu/projects/ribica/front-ui/node_modules/react/lib/keyMirror.js"}],"/home/senadu/projects/ribica/front-ui/app/constants/categoryConstants.js":[function(require,module,exports){ -var keyMirror = require('react/lib/keyMirror'); - -// Define action constants -module.exports = keyMirror({ - LOAD_CATEGORY_DETAILS: null -}); - - -},{"react/lib/keyMirror":"/home/senadu/projects/ribica/front-ui/node_modules/react/lib/keyMirror.js"}],"/home/senadu/projects/ribica/front-ui/app/constants/initializationConstants.js":[function(require,module,exports){ -var keyMirror = require('react/lib/keyMirror'); - -// Define action constants -module.exports = keyMirror({ - INITIALIZE: null -}); - -},{"react/lib/keyMirror":"/home/senadu/projects/ribica/front-ui/node_modules/react/lib/keyMirror.js"}],"/home/senadu/projects/ribica/front-ui/app/constants/itemConstants.js":[function(require,module,exports){ -var keyMirror = require('react/lib/keyMirror'); - -// Define action constants -module.exports = keyMirror({ - LOAD_FOR_FRONTPAGE: null, - LOAD_BSI_FOR_SECTION: null, - LOAD_BSI_FOR_ITEM_GROUP: null, - LOAD_BY_CATEGORY: null -}); - - -},{"react/lib/keyMirror":"/home/senadu/projects/ribica/front-ui/node_modules/react/lib/keyMirror.js"}],"/home/senadu/projects/ribica/front-ui/app/constants/itemDetailsConstants.js":[function(require,module,exports){ -var keyMirror = require('react/lib/keyMirror'); - -// Define action constants -module.exports = keyMirror({ - LOAD_ITEM_WITH_DETAILS: null, - NEXT_CAROUSEL_IMAGE: null, - PREVIOUS_CAROUSEL_IMAGE: null, - SELECT_CAROUSEL_IMAGE: null -}); - -},{"react/lib/keyMirror":"/home/senadu/projects/ribica/front-ui/node_modules/react/lib/keyMirror.js"}],"/home/senadu/projects/ribica/front-ui/app/constants/menuItemConstants.js":[function(require,module,exports){ -var keyMirror = require('react/lib/keyMirror'); - -// Define action constants -module.exports = keyMirror({ - LOAD_MENU_ITEMS: null, - SET_MENU_ITEM_HOVER: null, - UNSET_MENU_ITEM_HOVER: null -}); - - -},{"react/lib/keyMirror":"/home/senadu/projects/ribica/front-ui/node_modules/react/lib/keyMirror.js"}],"/home/senadu/projects/ribica/front-ui/app/constants/navigationConstants.js":[function(require,module,exports){ -var keyMirror = require('react/lib/keyMirror'); - -// Define action constants -module.exports = keyMirror({ - CHANGE_URL: null -}); - -},{"react/lib/keyMirror":"/home/senadu/projects/ribica/front-ui/node_modules/react/lib/keyMirror.js"}],"/home/senadu/projects/ribica/front-ui/app/constants/searchConstants.js":[function(require,module,exports){ -var keyMirror = require('react/lib/keyMirror'); - -// Define action constants -module.exports = keyMirror({ - SEARCH_BOX_CHANGE: null, - GET_SEARCH_RESULTS: null -}); - - -},{"react/lib/keyMirror":"/home/senadu/projects/ribica/front-ui/node_modules/react/lib/keyMirror.js"}],"/home/senadu/projects/ribica/front-ui/app/constants/sectionConstants.js":[function(require,module,exports){ -var keyMirror = require('react/lib/keyMirror'); - -// Define action constants -module.exports = keyMirror({ - LOAD_SECTIONS: null, - SET_SECTION_HOVER: null, - UNSET_SECTION_HOVER: null, - LOAD_SECTION_DETAILS: null -}); - - -},{"react/lib/keyMirror":"/home/senadu/projects/ribica/front-ui/node_modules/react/lib/keyMirror.js"}],"/home/senadu/projects/ribica/front-ui/app/constants/userConstants.js":[function(require,module,exports){ -var keyMirror = require('react/lib/keyMirror'); - -// Define action constants -module.exports = keyMirror({ - REGISTER_USER : null, - REGISTRATION_SUCCESS: null, - REGISTRATION_FAILURE: null, - USER_LOGIN: null, - LOGIN_SUCCESS: null, - LOGIN_FAILURE: null, - CHECK_LOGIN: null, - CHECK_LOGIN_ARRIVED: null, - USER_LOGOUT_DONE: null, - USER_LOGOUT: null -}); - - -},{"react/lib/keyMirror":"/home/senadu/projects/ribica/front-ui/node_modules/react/lib/keyMirror.js"}],"/home/senadu/projects/ribica/front-ui/app/dispatcher/appDispatcher.js":[function(require,module,exports){ -var Dispatcher = require('flux').Dispatcher; - -// Create dispatcher instance -var AppDispatcher = new Dispatcher(); - -// Convenience method to handle dispatch requests -AppDispatcher.handleAction = function(action) { - this.dispatch({ - source: 'VIEW_ACTION', - action: action - }); - - -} - -module.exports = AppDispatcher; - -},{"flux":"/home/senadu/projects/ribica/front-ui/node_modules/flux/index.js"}],"/home/senadu/projects/ribica/front-ui/app/externalApi.js":[function(require,module,exports){ -var App = function() { - this.bootstrap = function() { - // here goes all app initialization and bootstraping logic - // nothing at the moment - }; -}; - -var app = new App(); -module.exports = app; - - -},{}],"/home/senadu/projects/ribica/front-ui/app/globals.js":[function(require,module,exports){ -module.exports = { - ApiUrl: 'http://localhost:4567', - DefaultPageSize: 24, - ItemGroupIdOfStartPage: "1", - ItemGroupIdOfEmptyCartPage: "1", - FormatCurrency: function(amount_s) { - var amount = parseFloat(amount_s); - return ( amount.toFixed(2) + " KM" ) - }, - MaxNumberOfItemsToBeAdded: 1000 -}; - - -},{}],"/home/senadu/projects/ribica/front-ui/app/models/cart.js":[function(require,module,exports){ -var Backbone = require('backbone'); -var Globals = require('../globals'); - -var Cart = Backbone.Model.extend({ - - initialize: function() { - $.ajaxPrefilter( - function(options, originalOptions, jqXHR) { - options.xhrFields = { - withCredentials: true - } - } - ); - }, - urlRoot : Globals.ApiUrl + '/cart', - defaults : { - 'yes': 'yes' - } -}); - - -module.exports = Cart; - - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/category.js":[function(require,module,exports){ -var Backbone = require('backbone'); -var Globals = require('../globals'); - -var Category = Backbone.Model.extend({ - urlRoot : Globals.ApiUrl + '/category', - defaults : { - name: '', - filter_criterias: [], - sub_categories: [] - } -}); - - -module.exports = Category; - - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/categoryCollection.js":[function(require,module,exports){ - - -},{}],"/home/senadu/projects/ribica/front-ui/app/models/deliveryDestination.js":[function(require,module,exports){ -var Backbone = require('backbone'); -var Globals = require('../globals'); - -var DeliveryDestination = Backbone.Model.extend({ - - initialize: function() { - $.ajaxPrefilter( - function(options, originalOptions, jqXHR) { - options.xhrFields = { - withCredentials: true - } - } - ); - }, - - url: Globals.ApiUrl + '/cart/delivery_destination', - defaults: { - count: 0 - } -}); - -module.exports = DeliveryDestination; - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/item.js":[function(require,module,exports){ -var Backbone = require('backbone'); -var Globals = require('../globals'); - -var Item = Backbone.Model.extend({ - urlRoot : Globals.ApiUrl + '/item', - defaults : { - brand: {} - } - - - -}); - -module.exports = Item; - - - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/itemCollection.js":[function(require,module,exports){ -var Backbone = require('backbone'), - Item = require('./item'), - Globals = require('../globals'); - -var ItemCollection = Backbone.Collection.extend({ - - initialize: function() { - $.ajaxPrefilter( - function(options, originalOptions, jqXHR) { - options.xhrFields = { - withCredentials: true - } - } - ); - }, - setTotalCount: function(total) { - this.totalCount = total; - }, - addFilter: function(name, value) { - this.filters = this.filters || {}; - this.filters[name] = value; - }, - clearFilter: function() { - this.filters = []; - }, - setLimit: function(limit) { - this.queryLimit = limit; - }, - - setOffset: function(offset) { - this.offset = offset; - }, - - classificationTypeUrlParts: ['', 'section', 'category', 'sub_category', 'item_group'], - - setClassificationType: function(type) { - this.classificationType = type; - }, - - setClassificationId: function(id) { - this.classificationId = id; - }, - - setFromCart: function(fromCart) { - this.fromCart = fromCart; - }, - - model: Item, - url: function() { - if (this.fromCart === true) { - return Globals.ApiUrl + "/cart/item/display"; - } - - var path = '/item'; - - if (this.classificationType > 0) { - // eg. http://localhost:4567/item/section/1/offset/0/limit/10 - var urlPart = this.classificationTypeUrlParts[this.classificationType]; - path += "/" + urlPart + "/" + this.classificationId; - } // else eg. http://localhost:4567/item/offset/0/limit/10 - path += "/offset/" + this.offset + "/limit/" + this.queryLimit; - - var queryParts = []; - - for (var key in this.filters) { - if (this.filters.hasOwnProperty(key)) { - queryParts.push(key + '=' + this.filters[key]); - } - } - var query = ''; - - if (queryParts.length > 0) { - query = '?' + queryParts.join('&'); - } - - return Globals.ApiUrl + path + query; - } -}); - -module.exports = ItemCollection; - - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","./item":"/home/senadu/projects/ribica/front-ui/app/models/item.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/itemInCart.js":[function(require,module,exports){ -var Backbone = require('backbone'); -var Globals = require('../globals'); - -var ItemInCart = Backbone.Model.extend({ - - initialize: function() { - $.ajaxPrefilter( - function(options, originalOptions, jqXHR) { - options.xhrFields = { - withCredentials: true - } - } - ); - }, - - url: Globals.ApiUrl + '/cart/item', - defaults: { - count: 0 - } -}); - -module.exports = ItemInCart; - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/itemInCartCollection.js":[function(require,module,exports){ -var Backbone = require('backbone'), - ItemInCart = require('./itemInCart'), - Globals = require('../globals'); - -var ItemInCartCollection = Backbone.Collection.extend({ - - initialize: function() { - $.ajaxPrefilter( - function(options, originalOptions, jqXHR) { - options.xhrFields = { - withCredentials: true - } - } - ); - }, - - model: ItemInCart, - url: Globals.ApiUrl + '/cart/item' - - -}); - -module.exports = ItemInCartCollection; - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","./itemInCart":"/home/senadu/projects/ribica/front-ui/app/models/itemInCart.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/itemSearchCollection.js":[function(require,module,exports){ -var Backbone = require('backbone'), - Item = require('./item'), - Globals = require('../globals'); - -var ItemSearchCollection = Backbone.Collection.extend({ - initialize: function() { - $.ajaxPrefilter( - function(options, originalOptions, jqXHR) { - options.xhrFields = { - withCredentials: true - } - } - ); - }, - setQuery: function(q) { - this.q = q; - }, - model: Item, - url: function() { - return Globals.ApiUrl + "/search?q=" + this.q; - } -}); - -module.exports = ItemSearchCollection; - - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","./item":"/home/senadu/projects/ribica/front-ui/app/models/item.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/itemWithDetails.js":[function(require,module,exports){ -var Backbone = require('backbone'); -var Globals = require('../globals'); -var Mutators = require('Backbone.Mutators'); - -var ItemWithDetails = Backbone.Model.extend({ - - urlRoot: Globals.ApiUrl + '/item', - mutators: { - pricePerUnit: function() { - var unitsInPack = this.get('units_in_pack'); - if (unitsInPack == undefined || unitsInPack <= 1) return ""; - unitsInPack = parseFloat(unitsInPack).toFixed(0); - var price = parseFloat(this.get('list_price')).toFixed(2) - var pricePerUnit = (price / unitsInPack).toFixed(2); - var descriptionSuffix = this.get('unit').description_suffix; - return Globals.FormatCurrency(pricePerUnit); - } - }, - defaults : { - brand: {} - } - -}); - -module.exports = ItemWithDetails; - - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","Backbone.Mutators":"/home/senadu/projects/ribica/front-ui/node_modules/Backbone.Mutators/backbone.mutators.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/linkBanner.js":[function(require,module,exports){ -var Backbone = require('backbone'); -var Globals = require('../globals'); -var LinkBanner = Backbone.Model.extend({ - urlRoot : Globals.ApiUrl + '/link_banner' -}); - -module.exports = LinkBanner; - - - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/linkBannerCollection.js":[function(require,module,exports){ -var Backbone = require('backbone'), - LinkBanner = require('./linkBanner'), - Globals = require('../globals'); - -var LinkBannerCollection = Backbone.Collection.extend({ - model: LinkBanner, - url: Globals.ApiUrl + '/link_banner' -}); - -module.exports = LinkBannerCollection; - - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","./linkBanner":"/home/senadu/projects/ribica/front-ui/app/models/linkBanner.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/menuItem.js":[function(require,module,exports){ -var Backbone = require('backbone'); -var Globals = require('../globals'); -var MenuItem = Backbone.Model.extend({ - urlRoot : Globals.ApiUrl + '/menu_item', - defaults: { - title: '', - url: '', - sub_menu_items : [] - } -}); - -module.exports = MenuItem; - - - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/menuItemCollection.js":[function(require,module,exports){ -var Backbone = require('backbone'), - MenuItem = require('./menuItem'), - Globals = require('../globals'); - -var MenuItemCollection = Backbone.Collection.extend({ - model: MenuItem, - url: Globals.ApiUrl + '/menuitem' -}); - -module.exports = MenuItemCollection; - - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","./menuItem":"/home/senadu/projects/ribica/front-ui/app/models/menuItem.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/orderConfirmation.js":[function(require,module,exports){ -var Backbone = require('backbone'); -var Globals = require('../globals'); - -var orderConfirmation = Backbone.Model.extend({ - - initialize: function() { - $.ajaxPrefilter( - function(options, originalOptions, jqXHR) { - options.xhrFields = { - withCredentials: true - } - } - ); - }, - - url: Globals.ApiUrl + '/cart/confirmation', - defaults: { } -}); - -module.exports = orderConfirmation; - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/place.js":[function(require,module,exports){ -var Globals = require('../globals'); -var Backbone = require('backbone'); -var _ = require('underscore'); - -var FREE_SHIPPING_LIMIT = 50; - -var Place = Backbone.Model.extend({ - - initialize: function(options) { - options || (options = {}); - this.postalCode = options.postalCode; - }, - - url: function() { - var postalCode = this.postalCode || "00000"; - return Globals.ApiUrl + '/place/' + postalCode.trim(); - } - -}); - - - -module.exports = Place; - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js","underscore":"/home/senadu/projects/ribica/front-ui/node_modules/underscore/underscore.js"}],"/home/senadu/projects/ribica/front-ui/app/models/section.js":[function(require,module,exports){ -var Backbone = require('backbone'); -var Globals = require('../globals'); - -var Section = Backbone.Model.extend({ - urlRoot : Globals.ApiUrl + '/section', - defaults : { - name: '', - categories: [] - } -}); - - -module.exports = Section; - - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/sectionCollection.js":[function(require,module,exports){ -var Backbone = require('backbone'), - Section = require('./section'), - Globals = require('../globals'); - -var SectionCollection = Backbone.Collection.extend({ - model: Section, - url: Globals.ApiUrl + '/section' -}); - -module.exports = SectionCollection; - - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","./section":"/home/senadu/projects/ribica/front-ui/app/models/section.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/models/subCategory.js":[function(require,module,exports){ -var Backbone = require('backbone'); -var Globals = require('../globals'); - -var SubCategory = Backbone.Model.extend({ - urlRoot : Globals.ApiUrl + '/subcategory', - defaults : { - name: '', - filter_criterias: [] - } -}); - - -module.exports = SubCategory; - - -},{"../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js"}],"/home/senadu/projects/ribica/front-ui/app/ribica.js":[function(require,module,exports){ -var Backbone = require('backbone'); -var React = require('react'); -var ExternalApi = require('./externalApi'); -var Router = require('./router'); -Backbone.$ = $; - -Router.run(function(Handler, state) { - React.render(React.createElement(Handler, null), document.body); -}); - -module.exports = { - App: ExternalApi, - Router: Router -} - - -},{"./externalApi":"/home/senadu/projects/ribica/front-ui/app/externalApi.js","./router":"/home/senadu/projects/ribica/front-ui/app/router.js","backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js"}],"/home/senadu/projects/ribica/front-ui/app/router.js":[function(require,module,exports){ -var React = require('react'); -var Router = require('react-router'), - Route = Router.Route, DefaultRoute = Router.DefaultRoute; -var RouteHandler = Router.RouteHandler; -var Navigation = Router.Navigation; - -var ItemWithDetailsPage = require('./components/items/itemWithDetailsPage'); -var ItemList = require('./components/items/itemList'); -var SectionsListComponent = require('./components/shared/sectionsListComponent'); -var AllItems = require('./components/items/allItems'); -var ItemGroupPage = require('./components/items/itemGroupPage'); -var CartPage = require('./components/cart/cartPage'); -var CheckoutPage = require('./components/cart/checkoutPage'); -var RootApp = require('./components/rootApp'); -var StartPage = require('./components/startPage/startPage'); -var ByCategory = require('./components/browsing/byCategory'); -var BySubCategory = require('./components/browsing/bySubCategory'); -var BySection = require('./components/browsing/bySection'); -var ThankYouPage = require('./components/thankyou/thankYouPage'); -// var Register = require('./components/account/register'); -// var Login = require('./components/account/login'); -var SearchResultsPage = require('./components/search/searchResultsPage'); - - -var routes = ( - React.createElement(Route, {name: "app", path: "/", handler: RootApp}, - React.createElement(Route, {name: "sekcija", path: "sekcija/:id/:name", handler: BySection}), - React.createElement(Route, {name: "artikal", path: "artikal/:id/*", handler: ItemWithDetailsPage}), - React.createElement(Route, {name: "grupa", path: "grupa/:id/*", handler: ItemGroupPage}), - React.createElement(Route, {name: "korpa", path: "/korpa", handler: CartPage}), - React.createElement(Route, {name: "dostava", path: "/dostava", handler: CheckoutPage}), - /**/ - /**/ - React.createElement(Route, {name: "podkategorija", path: "/podkategorija/:id/*", handler: BySubCategory}), - React.createElement(Route, {name: "byCat", path: "sekcija/:sekcijaName/kategorija/:id/*", handler: ByCategory}), - React.createElement(Route, {name: "hvala", path: "/hvala", handler: ThankYouPage}), - React.createElement(Route, {name: "pretraga", path: "/pretraga", handler: SearchResultsPage}), - React.createElement(DefaultRoute, {handler: StartPage}) - ) - ); - -var router = Router.create({ - routes: routes, - location: Router.HistoryLocation -}); - -module.exports = router; - - -},{"./components/browsing/byCategory":"/home/senadu/projects/ribica/front-ui/app/components/browsing/byCategory.js","./components/browsing/bySection":"/home/senadu/projects/ribica/front-ui/app/components/browsing/bySection.js","./components/browsing/bySubCategory":"/home/senadu/projects/ribica/front-ui/app/components/browsing/bySubCategory.js","./components/cart/cartPage":"/home/senadu/projects/ribica/front-ui/app/components/cart/cartPage.js","./components/cart/checkoutPage":"/home/senadu/projects/ribica/front-ui/app/components/cart/checkoutPage.js","./components/items/allItems":"/home/senadu/projects/ribica/front-ui/app/components/items/allItems.js","./components/items/itemGroupPage":"/home/senadu/projects/ribica/front-ui/app/components/items/itemGroupPage.js","./components/items/itemList":"/home/senadu/projects/ribica/front-ui/app/components/items/itemList.js","./components/items/itemWithDetailsPage":"/home/senadu/projects/ribica/front-ui/app/components/items/itemWithDetailsPage.js","./components/rootApp":"/home/senadu/projects/ribica/front-ui/app/components/rootApp.js","./components/search/searchResultsPage":"/home/senadu/projects/ribica/front-ui/app/components/search/searchResultsPage.js","./components/shared/sectionsListComponent":"/home/senadu/projects/ribica/front-ui/app/components/shared/sectionsListComponent.js","./components/startPage/startPage":"/home/senadu/projects/ribica/front-ui/app/components/startPage/startPage.js","./components/thankyou/thankYouPage":"/home/senadu/projects/ribica/front-ui/app/components/thankyou/thankYouPage.js","react":"/home/senadu/projects/ribica/front-ui/node_modules/react/react.js","react-router":"/home/senadu/projects/ribica/front-ui/node_modules/react-router/modules/index.js"}],"/home/senadu/projects/ribica/front-ui/app/stores/bySubCategoryStore.js":[function(require,module,exports){ -var AppDispatcher = require('../dispatcher/appDispatcher'); -var EventEmitter = require('events').EventEmitter; -//var SubCategoryCollection = require('../models/subCategoryCollection'); -var SubCategory = require('../models/subCategory'); - -var NavigationActions = require('../actions/navigationActions'); -var BySubCategoryConstants = require('../constants/bySubCategoryConstants'); -var ItemCollection = require('../models/itemCollection'); -var _ = require('underscore'); - -var Globals = require('../globals'); - -var _state = { - subCategory : (new SubCategory()), - items: (new ItemCollection()), - filter: {}, - pagination: { - offset : 0, - limit: Globals.DefaultPageSize - } -}; -//var _categoryDetails = new Category(); - -//var loadSections = function() { - //var sections = new SectionCollection(); - //sections.fetch({success: function() { - //sectionState.sections = sections.models; - //// change will be called automatically when - //// action is run but we need to emit it again - //// when the data arive - //// it's a bit "unfluxy" but convenient. - //// "true philosophy" would be to run another "data arrived" action - //SectionStore.emitChange(); - //}}); -//}; -var fetchItemsBySubCategory = function(subCategoryId, offset, limit, query) { - //var items = _itemsByCategory; - query = query || {}; - var items = new ItemCollection(); - items.clearFilter(); - items.setClassificationType(3); - items.setClassificationId(subCategoryId); - items.setLimit(limit); - items.setOffset(offset); - - for(var key in query) { - if (query.hasOwnProperty(key) && key != 'limit' && key !='offset') { - items.addFilter(key, query[key]); - } - } - - items.fetch({ - success: function(collection, response, options) { - var total = options.xhr.getResponseHeader('x-total-count'); - items.setTotalCount(total); - - _state.items = items; - BySubCategoryStore.emitChange(); - }}); - -}; -var load = function(subCategoryId, offset, limit, filter) { - - var subCategory = new SubCategory({id : subCategoryId}); - subCategory.fetch({ - success: function() { - _state.subCategory = subCategory; - fetchItemsBySubCategory(subCategoryId, offset, limit, filter); - - } - }); - _state.filter = filter; - _state.pagination.limit = limit; - _state.pagination.offset = offset; -}; - -var handleFilterCriteriaClick = function(fc, fcv) { - _state.filter[fc.field_name] = fcv.filter_value; - - setTimeout(function() { - NavigationActions.goToSubCategory(_state.subCategory, 0, _state.pagination.limit, _state.filter); - }, 0); -}; - -var handleRemoveAppliedFilter= function(name) { - delete _state.filter[name]; - - setTimeout(function() { - NavigationActions.goToSubCategory(_state.subCategory, 0, _state.pagination.limit, _state.filter); - }, 0); -}; - -var handleChangePage = function(page) { - setTimeout(function() { - NavigationActions.goToSubCategory(_state.subCategory, parseInt(page) * _state.pagination.limit, _state.pagination.limit, _state.filter); - }, 0); -}; - - - -// Extend SectionStore with EventEmitter to add eventing capabilities -var BySubCategoryStore = _.extend({}, EventEmitter.prototype, { - - getState: function() { - return _state; - }, - // Emit Change event - emitChange: function() { - - this.emit('change'); - }, - - // Add change listener - addChangeListener: function(callback) { - this.on('change', callback); - }, - - // Remove change listener - removeChangeListener: function(callback) { - this.removeListener('change', callback); - } -}); - - -// Register callback with AppDispatcher -AppDispatcher.register(function(payload) { - var action = payload.action; - var text; - - switch(action.actionType) { - - case BySubCategoryConstants.LOAD: - load(action.subCategoryId, action.offset, action.limit, action.filter); - break; - - case BySubCategoryConstants.FILTER_CRITERIA_CLICK: - handleFilterCriteriaClick(action.fc, action.fcv); - break; - case BySubCategoryConstants.REMOVE_APPLIED_FILTER: - handleRemoveAppliedFilter(action.name); - break; - case BySubCategoryConstants.CHANGE_PAGE: - handleChangePage(action.page); - break; - - // Respond to SELECT_ITEM action - //case SectionConstants.LOAD_SECTIONS: - //loadSections(); - //break; - - //case SectionConstants.SET_SECTION_HOVER: - //setHovered(action.section.get('id')); - //break; - - //case SectionConstants.UNSET_SECTION_HOVER: - //setHovered(''); - //break; - - //case CategoryConstants.LOAD_CATEGORY_DETAILS: - //loadCategoryDetails(action.categoryId); - //break; - - default: - return true; - } - - // If action was responded to, emit change event - BySubCategoryStore.emitChange(); - return true; - -}); - -module.exports = BySubCategoryStore; - - -},{"../actions/navigationActions":"/home/senadu/projects/ribica/front-ui/app/actions/navigationActions.js","../constants/bySubCategoryConstants":"/home/senadu/projects/ribica/front-ui/app/constants/bySubCategoryConstants.js","../dispatcher/appDispatcher":"/home/senadu/projects/ribica/front-ui/app/dispatcher/appDispatcher.js","../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","../models/itemCollection":"/home/senadu/projects/ribica/front-ui/app/models/itemCollection.js","../models/subCategory":"/home/senadu/projects/ribica/front-ui/app/models/subCategory.js","events":"/home/senadu/projects/ribica/front-ui/node_modules/events/events.js","underscore":"/home/senadu/projects/ribica/front-ui/node_modules/underscore/underscore.js"}],"/home/senadu/projects/ribica/front-ui/app/stores/cartStore.js":[function(require,module,exports){ -var AppDispatcher = require('../dispatcher/appDispatcher'); -var EventEmitter = require('events').EventEmitter; -var CartConstants = require('../constants/cartConstants'); -var CartActions = require('../actions/cartActions'); -var NavigationActions = require('../actions/navigationActions'); -var ItemInCart = require('../models/itemInCart'); -var ItemInCartCollection = require('../models/itemInCartCollection'); -var ItemCollection = require('../models/itemCollection'); -var DeliveryDestination = require('../models/deliveryDestination'); -var OrderConfirmation = require('../models/orderConfirmation'); -var Place = require('../models/place'); -var Validation = require('../utils/validation'); - -var _ = require('underscore'); - -var states = {} - -var _itemsInCart = new ItemInCartCollection(); -var _itemsForDisplay = new ItemCollection(); -_itemsForDisplay.setFromCart(true); - -var _deliveryDestination = new DeliveryDestination(); -var _deliveryDestinationErrors = {}; -var _deliveryCosts = new Place({ - postalCode: _deliveryDestination.get('place') -}) - - -var supportedPlaces = [ -{ - "code": "-12", - "placeLabel": "Izaberite mjesto" -}, { - "code": "-13", - "placeLabel": "-------------------------------" -}, { - "code": " 71000", - "placeLabel": "Sarajevo" -}, { - "code": " 71103", - "placeLabel": "Sarajevo, Centar" -}, { - "code": " 71160", - "placeLabel": "Sarajevo, Novi Grad" -}, { - "code": " 71120", - "placeLabel": "Sarajevo, Novo Sarajevo" -}, { - "code": " 71140", - "placeLabel": "Sarajevo, Stari Grad" -}, { - "code": " 78000", - "placeLabel": "Banja Luka" -}, { - "code": " 75000", - "placeLabel": "Tuzla" -}, { - "code": " 72000", - "placeLabel": "Zenica" -}, { - "code": " 88000", - "placeLabel": "Mostar" -}, { - "code": " 88000", - "placeLabel": "Mostar, Jug" -}, { - "code": " 88000", - "placeLabel": "Mostar, Jugozapad" -}, { - "code": " 88000", - "placeLabel": "Mostar, Sjever" -}, { - "code": " 88000", - "placeLabel": "Mostar, Zapad" -}, { - "code": "71300", - "placeLabel": "Visoko" -}, { - "code": "71240", - "placeLabel": "Hadžići" -}]; - -var _cartDataLoadCalled = false; - -var loadCart = function() { - - _itemsInCart.fetch({ - success: function() { - states = {} - for (var i = 0; i < _itemsInCart.models.length; i++) { - var itemInCart = _itemsInCart.models[i]; - states[itemInCart.get('item_id')] = itemInCart; - } - _itemsForDisplay.fetch({ - success: function() { - CartActions.dataLoaded(); - - _deliveryDestination.fetch({ - success: function() { - validateDeliveryDestinationForm(); - fetchPlace(); - CartActions.dataLoaded(); - } - }); - } - }); - } - }); - - _cartDataLoadCalled = true; -}; - - -var fetchPlace = function() { - _deliveryCosts = new Place({ - postalCode: _deliveryDestination.get('place') - }) - _deliveryCosts.fetch({ - success: function() { - CartActions.dataLoaded(); - } - }) - -} - - -var saveCartStateForItem = function(itemId) { - var item = CartStore.getStateFor(itemId); - item.save({ - success: function() { - loadCart(); - } - }); -}; - -/* need it for delete - will delete it later - */ -var takeItemOut = function(itemId) { - - var state = states[itemId] || new ItemInCart({ - item_id: itemId, - count: 0 - }) - if (state.get('count') > 0) { - // state.set('count', state.get('count') - 1); - state.set('count', 0); - } - - states[itemId] = state; - saveCartStateForItem(itemId); -}; - -var setItemCount = function(itemId, count) { - var state = states[itemId] || new ItemInCart({ - item_id: itemId, - count: 0 - }); - - if (count === "") { - state.set('count', ""); - CartStore.emitChange(); - return; - } - - var cnt = parseInt(count); - - if (isNaN(cnt) || cnt <= 0) { - cnt = 1; - } - - state.set('count', cnt); - - states[itemId] = state; - saveCartStateForItem(itemId); - // CartStore.emitChange(); -}; - -var addNItems = function(item, count) { - - var itemId = item.get('id'); - var state = states[itemId] || new ItemInCart({ - item_id: itemId, - count: 0 - }) - - _itemsForDisplay.add(item); - - var realCount = state.get('count') + count; - - // remove if we choose to support more than - // 10 items of single type in cart - if (realCount > 10) { - realCount = 10; - - } - state.set('count', realCount); - - states[itemId] = state; - saveCartStateForItem(itemId); -} - -var changeDeliveryDestinationProperty = function(property, value) { - _deliveryDestination.set(property, value); - - if (property === 'place') { - fetchPlace(); - } - validateDeliveryDestinationForm(); -}; - - -var confirmOrder = function() { - - var oc = new OrderConfirmation({ - hamo: 'meho' - }); - oc.save({ - b: 'b' - }, { - success: function() { - - NavigationActions.goToThankYou(); - loadCart(); - } - }); -}; - - -var saveDeliveryDestination = function() { - _deliveryDestination.save(null, { - success: function() { - - confirmOrder(); - } - }) -}; - -var validateDeliveryDestinationForm = function() { - _deliveryDestinationErrors = {}; - - var nameRegex = /.+\s+.+/i; - if (Validation.safeString(_deliveryDestination.get('name')).search(nameRegex) < 0) { - _deliveryDestinationErrors['name'] = "I prezime i ime su obavezni"; - } - - var addressRegex = /.+\s+.+/i; - if (Validation.safeString(_deliveryDestination.get('address')).search(addressRegex) < 0) { - _deliveryDestinationErrors['address'] = "Adresa mora biti ispravna"; - } - - var emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/i; - if (Validation.safeString(_deliveryDestination.get('email')).search(emailRegex) < 0) { - _deliveryDestinationErrors['email'] = "Email mora biti ispravno upisan"; - } - - var phoneRegex = /^[\d\s-]{8,12}$/i; - if (Validation.safeString(_deliveryDestination.get('phone')).search(phoneRegex) < 0) { - _deliveryDestinationErrors['phone'] = "Telefon mora biti ispravan"; - } - - var placeRegex = /^\s{0,1}\d{5}$/i; - if (Validation.safeString(_deliveryDestination.get('place')).search(placeRegex) < 0) { - _deliveryDestinationErrors['place'] = "Mjesto mora biti izabrano"; - } - - var requiredFields = ["name", "email", "place", 'address', 'phone']; - for (var i in requiredFields) { - var value = _deliveryDestination.get(requiredFields[i]); - if (value === undefined || value === null || value === "") { - // if it's required there will be a star there - _deliveryDestinationErrors[requiredFields[i]] = "*"; - } - } - -} - - -var isDeliveryDestinationValid = function() { - return Object.getOwnPropertyNames(_deliveryDestinationErrors).length === 0; - } - // Extend CartStore with EventEmitter to add eventing capabilities -var CartStore = _.extend({}, EventEmitter.prototype, { - - dataStartedLoading: function() { - return _cartDataLoadCalled; - }, - - getStateFor: function(itemId) { - - var state = states[itemId] || new ItemInCart({ - item_id: itemId, - count: 0 - }) - return state - }, - - getSupportedPlaces: function() { - return supportedPlaces; - }, - - getWholeCartState: function() { - - var numberOfItems = 0; - - for (key in states) { - if (states.hasOwnProperty(key)) { - var value = states[key]; - if (value.get('count') > 0) { - numberOfItems += value.get('count'); - } - } - }; - - var state = { - count: numberOfItems, - items: _itemsForDisplay, - itemCounts: states, - deliveryDestination: _deliveryDestination, - deliveryDestinationErrors: _deliveryDestinationErrors, - isDeliveryDestinationValid: isDeliveryDestinationValid(), - deliveryCosts: _deliveryCosts, - destinationValid: isDeliveryDestinationValid() - }; - return state; - }, - - // Emit Change event - emitChange: function() { - this.emit('change'); - }, - - // Add change listener - addChangeListener: function(callback) { - this.on('change', callback); - }, - - // Remove change listener - removeChangeListener: function(callback) { - this.removeListener('change', callback); - }, - - isDeliveryDestinationValid: isDeliveryDestinationValid - - - -}); - - -// Register callback with AppDispatcher -AppDispatcher.register(function(payload) { - var action = payload.action; - var text; - - switch (action.actionType) { - case CartConstants.LOAD_CART_CONTENTS: - loadCart(); - break; - case CartConstants.TAKE_ITEM_OUT: - takeItemOut(action.itemId); - break; - case CartConstants.CART_DATA_LOADED: - // do nothing - just emmit change - break; - case CartConstants.SAVE_CART_STATE_FOR_ITEM: - if (isDeliveryDestinationValid()) { - saveCartStateForItem(action.itemId); - } - break; - case CartConstants.CHANGE_DELIVERY_DESTINATION_PROPERTY: - changeDeliveryDestinationProperty(action.propertyName, action.value) - break; - case CartConstants.CONFIRM_DELIVERY: - saveDeliveryDestination(); - break; - case CartConstants.ADD_N_ITEMS: - addNItems(action.item, action.count); - break; - case CartConstants.SET_ITEM_COUNT: - setItemCount(action.itemId, action.count); - break; - default: - return true; - } - - // If action was responded to, emit change event - CartStore.emitChange(); - return true; - -}); - -module.exports = CartStore; - -},{"../actions/cartActions":"/home/senadu/projects/ribica/front-ui/app/actions/cartActions.js","../actions/navigationActions":"/home/senadu/projects/ribica/front-ui/app/actions/navigationActions.js","../constants/cartConstants":"/home/senadu/projects/ribica/front-ui/app/constants/cartConstants.js","../dispatcher/appDispatcher":"/home/senadu/projects/ribica/front-ui/app/dispatcher/appDispatcher.js","../models/deliveryDestination":"/home/senadu/projects/ribica/front-ui/app/models/deliveryDestination.js","../models/itemCollection":"/home/senadu/projects/ribica/front-ui/app/models/itemCollection.js","../models/itemInCart":"/home/senadu/projects/ribica/front-ui/app/models/itemInCart.js","../models/itemInCartCollection":"/home/senadu/projects/ribica/front-ui/app/models/itemInCartCollection.js","../models/orderConfirmation":"/home/senadu/projects/ribica/front-ui/app/models/orderConfirmation.js","../models/place":"/home/senadu/projects/ribica/front-ui/app/models/place.js","../utils/validation":"/home/senadu/projects/ribica/front-ui/app/utils/validation.js","events":"/home/senadu/projects/ribica/front-ui/node_modules/events/events.js","underscore":"/home/senadu/projects/ribica/front-ui/node_modules/underscore/underscore.js"}],"/home/senadu/projects/ribica/front-ui/app/stores/categoryStore.js":[function(require,module,exports){ -var AppDispatcher = require('../dispatcher/appDispatcher'); -var EventEmitter = require('events').EventEmitter; - -var CategoryCollection = require('../models/categoryCollection'); -var Category = require('../models/category'); - -var CategoryConstants = require('../constants/categoryConstants'); -var _ = require('underscore'); - -var _categoryDetails = new Category(); - -//var loadSections = function() { - //var sections = new SectionCollection(); - //sections.fetch({success: function() { - //sectionState.sections = sections.models; - //// change will be called automatically when - //// action is run but we need to emit it again - //// when the data arive - //// it's a bit "unfluxy" but convenient. - //// "true philosophy" would be to run another "data arrived" action - //SectionStore.emitChange(); - //}}); -//}; - -var loadCategoryDetails = function(categoryId) { - var category = new Category({id : categoryId}); - category.fetch({ - success: function() { - _categoryDetails = category; - CategoryStore.emitChange(); - } - }); -}; - -//var setHovered = function(id) { - //sectionState.hoveredSection = id; -//} - - -// Extend SectionStore with EventEmitter to add eventing capabilities -var CategoryStore = _.extend({}, EventEmitter.prototype, { - - getCategoryDetails: function() { - return _categoryDetails; - }, - // Emit Change event - emitChange: function() { - - this.emit('change'); - }, - - // Add change listener - addChangeListener: function(callback) { - this.on('change', callback); - }, - - // Remove change listener - removeChangeListener: function(callback) { - this.removeListener('change', callback); - } -}); - - -// Register callback with AppDispatcher -AppDispatcher.register(function(payload) { - var action = payload.action; - var text; - - switch(action.actionType) { - - // Respond to SELECT_ITEM action - //case SectionConstants.LOAD_SECTIONS: - //loadSections(); - //break; - - //case SectionConstants.SET_SECTION_HOVER: - //setHovered(action.section.get('id')); - //break; - - //case SectionConstants.UNSET_SECTION_HOVER: - //setHovered(''); - //break; - - case CategoryConstants.LOAD_CATEGORY_DETAILS: - loadCategoryDetails(action.categoryId); - break; - - default: - return true; - } - - // If action was responded to, emit change event - CategoryStore.emitChange(); - return true; - -}); - -module.exports = CategoryStore; - - -},{"../constants/categoryConstants":"/home/senadu/projects/ribica/front-ui/app/constants/categoryConstants.js","../dispatcher/appDispatcher":"/home/senadu/projects/ribica/front-ui/app/dispatcher/appDispatcher.js","../models/category":"/home/senadu/projects/ribica/front-ui/app/models/category.js","../models/categoryCollection":"/home/senadu/projects/ribica/front-ui/app/models/categoryCollection.js","events":"/home/senadu/projects/ribica/front-ui/node_modules/events/events.js","underscore":"/home/senadu/projects/ribica/front-ui/node_modules/underscore/underscore.js"}],"/home/senadu/projects/ribica/front-ui/app/stores/initializationStore.js":[function(require,module,exports){ -var AppDispatcher = require('../dispatcher/appDispatcher'); -var EventEmitter = require('events').EventEmitter; -var Cart = require('../models/cart'); -var LinkBannerCollection = require('../models/linkBannerCollection'); - -var InitializationConstants = require('../constants/initializationConstants') -var _ = require('underscore'); - -var banners = {}; - - -var state = { - isEverythingReadyToStartTheShow: false -}; - -var initializeTheShop = function () { - // for now only guarantee that cart is created - var cart = new Cart(); - cart.save(null, { - success: function () { - - state.isEverythingReadyToStartTheShow = true; - InitializationStore.emitChange(); - - } - }) - - initializeBanners(); - - -}; - - -var putBannerOnItsPlace = function(banners, lb) { - - - if(lb.get('start_page')) banners['startPage'].push(lb); - if(lb.get('thank_you_page')) banners['thankYouPage'].push(lb); - if(lb.get('search_result_page')) banners['searchResultPage'].push(lb); - if(lb.get('checkout_page')) banners['checkoutPage'].push(lb); - - var itemId = lb.get('item_id'); - if (itemId) { - banners['item'][itemId] = banners['item'][itemId] || []; - banners['item'][itemId].push(lb); - } - - var sectionId = lb.get('section_id'); - if (sectionId) { - banners['section'][sectionId] = banners['section'][sectionId] || []; - banners['section'][sectionId].push(lb); - } - - var categoryId = lb.get('category_id'); - if (categoryId) { - banners['category'][categoryId] = banners['category'][categoryId] || []; - banners['category'][categoryId].push(lb); - } - - var subCategoryId = lb.get('sub_category_id'); - if (subCategoryId) { - banners['subCategory'][subCategoryId] = banners['subCategory'][subCategoryId] || []; - banners['subCategory'][subCategoryId].push(lb); - } - -}; - -var initializeBanners = function() { - banners["startPage"] = []; - banners["searchResultPage"] = []; - banners["thankYouPage"] = []; - banners["checkoutPage"] = []; - banners["header"] = []; - banners["footer"] = []; - banners["section"] = {}; - banners["category"] = {}; - banners["subCategory"] = {}; - banners["item"] = {}; - - var lbc = new LinkBannerCollection(); - lbc.fetch({ - success: function() { - lbc.each(function(linkBanner) { - putBannerOnItsPlace( banners, linkBanner ); - } ); - - InitializationStore.emitChange(); - } - }); - -}; - - - -// Extend ItemStore with EventEmitter to add eventing capabilities -var InitializationStore = _.extend({}, EventEmitter.prototype, { - - getState: function() { - return state; - }, - - - getBanners: function() { - return banners; - }, - - // Emit Change event - emitChange: function() { - - this.emit('change'); - }, - - // Add change listener - addChangeListener: function(callback) { - this.on('change', callback); - }, - - // Remove change listener - removeChangeListener: function(callback) { - this.removeListener('change', callback); - } - -}); - - -// Register callback with AppDispatcher -InitializationStore.dispatchToken = AppDispatcher.register(function(payload) { - var action = payload.action; - - switch (action.actionType) { - - case InitializationConstants.INITIALIZE: - initializeTheShop(); - break; - default: - return true; - } - - // If action was responded to, emit change event - InitializationStore.emitChange(); - return true; - -}); - -module.exports = InitializationStore; - -},{"../constants/initializationConstants":"/home/senadu/projects/ribica/front-ui/app/constants/initializationConstants.js","../dispatcher/appDispatcher":"/home/senadu/projects/ribica/front-ui/app/dispatcher/appDispatcher.js","../models/cart":"/home/senadu/projects/ribica/front-ui/app/models/cart.js","../models/linkBannerCollection":"/home/senadu/projects/ribica/front-ui/app/models/linkBannerCollection.js","events":"/home/senadu/projects/ribica/front-ui/node_modules/events/events.js","underscore":"/home/senadu/projects/ribica/front-ui/node_modules/underscore/underscore.js"}],"/home/senadu/projects/ribica/front-ui/app/stores/itemDetailsStore.js":[function(require,module,exports){ -var AppDispatcher = require('../dispatcher/appDispatcher'); -var EventEmitter = require('events').EventEmitter; -var ItemDetailsConstants = require('../constants/itemDetailsConstants'); -var ItemWithDetails = require('../models/itemWithDetails'); -var _ = require('underscore'); - - -var _itemWithDetails = new ItemWithDetails(); -var _images = []; -var _currentImage = 0; -var _animating = false; -var _count; - - -var getItemIdFromUrl = function() { - // ugly but it seems to me that - // router does not want to expose its - // state (for phylosophical reasons) - var url = document.URL; - var itemIdRegex = /artikal\/(\d+)\//g; - var match = itemIdRegex.exec(url); - - return match[1]; -}; - -var fetchItemWithDetails = function() { - var id = getItemIdFromUrl(); - if (id !== undefined && _itemWithDetails.id !== id) { - var item = new ItemWithDetails({ - id: id - }); - _itemWithDetails = item; - item.fetch({ - success: function() { - _images = (_itemWithDetails.get("multi_media_descriptions") || []).map(function(mmd) { - return mmd.resized_url; - }); - _count = _images.length; - _currentImage = 0; - _animating = false; - ItemWithDetailsStore.emitChange(); - } - }); - } -}; - -var handlNextImage = function() { - if (_animating) return; - var next = _currentImage + 1; - if (next >= _count) next = 0; - handleSelectImage(next); -}; - -var handlePrevImage = function() { - if (_animating) return; - var next = _currentImage - 1; - if (next < 0) next = _count - 1; - handleSelectImage(next); -}; - - -var handleSelectImage = function(index) { - if (_animating) return; - _animating = true; - _currentImage = index; - setTimeout(function() { - _animating = false; - }, 300); -}; - - - -// Extend ItemWithDetailsStore with EventEmitter to add eventing capabilities -var ItemWithDetailsStore = _.extend({}, EventEmitter.prototype, { - - getState: function() { - - - var firstImage = _images[0] || "https://res.cloudinary.com/lfvt7ps2n/image/upload/c_fit,h_172,w_226/v1421732950/http_www.asms.ru_bitrix_templates_main_images_nophoto_irnofq.png"; - return { - item: _itemWithDetails, - images: _images, - currentImage: _currentImage, - count: _count, - firstImage: firstImage - } - - }, - - - // item with details - getLoadedItemWithDetails: function() { - return _itemWithDetails; - }, - - // Emit Change event - emitChange: function() { - this.emit('change'); - }, - - // Add change listener - addChangeListener: function(callback) { - this.on('change', callback); - }, - - // Remove change listener - removeChangeListener: function(callback) { - this.removeListener('change', callback); - } - -}); - - -// Register callback with AppDispatcher -AppDispatcher.register(function(payload) { - var action = payload.action; - var text; - - switch (action.actionType) { - - case ItemDetailsConstants.LOAD_ITEM_WITH_DETAILS: - fetchItemWithDetails(); - break; - - case ItemDetailsConstants.NEXT_CAROUSEL_IMAGE: - handlNextImage(); - break; - - case ItemDetailsConstants.PREVIOUS_CAROUSEL_IMAGE: - handlePrevImage(); - break; - - case ItemDetailsConstants.SELECT_CAROUSEL_IMAGE: - handleSelectImage(action.index); - break; - - default: - return true; - } - - // If action was responded to, emit change event - ItemWithDetailsStore.emitChange(); - return true; - -}); - -module.exports = ItemWithDetailsStore; - -},{"../constants/itemDetailsConstants":"/home/senadu/projects/ribica/front-ui/app/constants/itemDetailsConstants.js","../dispatcher/appDispatcher":"/home/senadu/projects/ribica/front-ui/app/dispatcher/appDispatcher.js","../models/itemWithDetails":"/home/senadu/projects/ribica/front-ui/app/models/itemWithDetails.js","events":"/home/senadu/projects/ribica/front-ui/node_modules/events/events.js","underscore":"/home/senadu/projects/ribica/front-ui/node_modules/underscore/underscore.js"}],"/home/senadu/projects/ribica/front-ui/app/stores/itemStore.js":[function(require,module,exports){ -var AppDispatcher = require('../dispatcher/appDispatcher'); -var EventEmitter = require('events').EventEmitter; -var ItemConstants = require('../constants/itemConstants'); -var ItemCollection = require('../models/itemCollection'); -var ItemWithDetails = require('../models/itemWithDetails'); -var _ = require('underscore'); - -// Define initial data points -var _items = new ItemCollection(), - _itemWithDetails = new ItemWithDetails(), - _bestSellingForSection = new ItemCollection(), - _itemsByCategory = new ItemCollection(), - _bestSellingForGroup = new ItemCollection(); - - -var loadItemsForFrontpage = function() { - items = _items - items.setClassificationType(0); - items.setLimit(30); - items.setOffset(0); - - items.fetch({ - success: function() { - ItemStore.emitChange(); - } - }); -}; - -var getItemIdFromUrl = function() { - // ugly but it seems to me that - // router does not want to expose its - // state - var url = document.URL; - var itemIdRegex = /artikal\/(\d+)\//g; - var match = itemIdRegex.exec(url); - - if (match) { - return match[1]; - } -}; - -var fetchItemWithDetails = function() { - var id = getItemIdFromUrl(); - if (id !== undefined && _itemWithDetails.id !== id) { - var item = new ItemWithDetails({ - id: id - }); - item.fetch({ - success: function() { - _itemWithDetails = item; - ItemStore.emitChange(); - } - }); - } -} - -var fetchItemsByCategory = function(categoryId, offset, limit, query) { - //var items = _itemsByCategory; - var items = new ItemCollection(); - items.clearFilter(); - items.setClassificationType(2); - items.setClassificationId(categoryId); - items.setLimit(limit); - items.setOffset(offset); - - for (var key in query) { - if (query.hasOwnProperty(key) && key != 'limit' && key != 'offset') { - items.addFilter(key, query[key]); - } - } - - items.fetch({ - success: function(collection, response, options) { - var total = options.xhr.getResponseHeader('x-total-count'); - items.setTotalCount(total); - - ItemStore.emitChange(); - } - }); - - _itemsByCategory = items; -}; - -var fetchBestSellingItemsForSection = function(sectionId) { - - var items = _bestSellingForSection; - items.setClassificationType(1); - items.setClassificationId(sectionId); - items.setLimit(30); - items.setOffset(0); - - items.fetch({ - success: function() { - ItemStore.emitChange(); - } - }); -}; - - -var fetchBestSellingItemsForGroup = function(groupId) { - - var items = _bestSellingForGroup; - items.setClassificationType(4); - items.setClassificationId(groupId); - items.setLimit(30); - items.setOffset(0); - - items.fetch({ - success: function() { - ItemStore.emitChange(); - } - }); -}; - - -// Extend ItemStore with EventEmitter to add eventing capabilities -var ItemStore = _.extend({}, EventEmitter.prototype, { - - getItemsForCategory: function() { - return _itemsByCategory; - }, - getBestSellingForSection: function() { - - return _bestSellingForSection; - }, - // item with details - getLoadedItemWithDetails: function() { - return _itemWithDetails; - }, - - getItemsForGroup: function() { - return _bestSellingForGroup; - }, - - - // Return All Items - getItems: function() { - return _items; - }, - - // Emit Change event - emitChange: function() { - - this.emit('change'); - }, - - // Add change listener - addChangeListener: function(callback) { - this.on('change', callback); - }, - - // Remove change listener - removeChangeListener: function(callback) { - this.removeListener('change', callback); - } - -}); - - -// Register callback with AppDispatcher -AppDispatcher.register(function(payload) { - var action = payload.action; - var text; - - switch (action.actionType) { - - case ItemConstants.LOAD_ITEM_WITH_DETAILS: - fetchItemWithDetails(); - break; - - case ItemConstants.LOAD_BSI_FOR_SECTION: - fetchBestSellingItemsForSection(action.sectionId); - break; - - case ItemConstants.LOAD_BSI_FOR_ITEM_GROUP: - fetchBestSellingItemsForGroup(action.groupId); - break; - - case ItemConstants.LOAD_FOR_FRONTPAGE: - loadItemsForFrontpage(); - break; - case ItemConstants.LOAD_BY_CATEGORY: - fetchItemsByCategory(action.categoryId, action.offset, action.limit, action.query); - break; - - default: - return true; - } - - // If action was responded to, emit change event - ItemStore.emitChange(); - return true; - -}); - -module.exports = ItemStore; - - -},{"../constants/itemConstants":"/home/senadu/projects/ribica/front-ui/app/constants/itemConstants.js","../dispatcher/appDispatcher":"/home/senadu/projects/ribica/front-ui/app/dispatcher/appDispatcher.js","../models/itemCollection":"/home/senadu/projects/ribica/front-ui/app/models/itemCollection.js","../models/itemWithDetails":"/home/senadu/projects/ribica/front-ui/app/models/itemWithDetails.js","events":"/home/senadu/projects/ribica/front-ui/node_modules/events/events.js","underscore":"/home/senadu/projects/ribica/front-ui/node_modules/underscore/underscore.js"}],"/home/senadu/projects/ribica/front-ui/app/stores/menuItemStore.js":[function(require,module,exports){ -var AppDispatcher = require('../dispatcher/appDispatcher'); -var EventEmitter = require('events').EventEmitter; -var MenuItemCollection = require('../models/menuItemCollection'); -var MenuItem = require('../models/menuItem'); -var MenuItemConstants = require('../constants/menuItemConstants'); -var _ = require('underscore'); - -var menuItemState = { - menuItems : [], - hoveredMenuItem : '' -}; - - -var loadMenuItems = function() { - var menuItems = new MenuItemCollection(); - menuItems.fetch({success: function() { - menuItemState.menuItems = menuItems.models; - // change will be called automatically when - // action is run but we need to emit it again - // when the data arive - // it's a bit "unfluxy" but convenient. - // "true philosophy" would be to run another "data arrived" action - MenuItemStore.emitChange(); - }}); -}; - -var setHovered = function(id) { - menuItemState.hoveredMenuItem = id; -} - - -// Extend MenuItemStore with EventEmitter to add eventing capabilities -var MenuItemStore = _.extend({}, EventEmitter.prototype, { - - // Return Single Item With Details - getState: function() { - return menuItemState; - }, - // Emit Change event - emitChange: function() { - this.emit('change'); - }, - - // Add change listener - addChangeListener: function(callback) { - this.on('change', callback); - }, - - // Remove change listener - removeChangeListener: function(callback) { - this.removeListener('change', callback); - } -}); - - -// Register callback with AppDispatcher -AppDispatcher.register(function(payload) { - var action = payload.action; - var text; - - switch(action.actionType) { - - // Respond to SELECT_ITEM action - case MenuItemConstants.LOAD_MENU_ITEMS: - loadMenuItems(); - break; - - case MenuItemConstants.SET_MENU_ITEM_HOVER: - setHovered(action.menuItem.get('id')); - break; - - case MenuItemConstants.UNSET_MENU_ITEM_HOVER: - setHovered(''); - break; - default: - return true; - } - - // If action was responded to, emit change event - MenuItemStore.emitChange(); - return true; - -}); - -module.exports = MenuItemStore; - - -},{"../constants/menuItemConstants":"/home/senadu/projects/ribica/front-ui/app/constants/menuItemConstants.js","../dispatcher/appDispatcher":"/home/senadu/projects/ribica/front-ui/app/dispatcher/appDispatcher.js","../models/menuItem":"/home/senadu/projects/ribica/front-ui/app/models/menuItem.js","../models/menuItemCollection":"/home/senadu/projects/ribica/front-ui/app/models/menuItemCollection.js","events":"/home/senadu/projects/ribica/front-ui/node_modules/events/events.js","underscore":"/home/senadu/projects/ribica/front-ui/node_modules/underscore/underscore.js"}],"/home/senadu/projects/ribica/front-ui/app/stores/navigationStore.js":[function(require,module,exports){ -var AppDispatcher = require('../dispatcher/appDispatcher'); -var EventEmitter = require('events').EventEmitter; -var Globals = require('../globals'); - -var NavigationConstants = require('../constants/navigationConstants') -var _ = require('underscore'); - - - - -var getGroupIdFromUrl = function() { - // ugly but it seems to me that - // router does not want to expose its - // state (for phylosophical reasons) - var url = document.URL; - var itemIdRegex = /grupa\/(\d+)\//g; - var match = itemIdRegex.exec(url); - - var result = Globals.ItemGroupIdOfStartPage; - if (match) { - result = match[1] - } - return result; -}; - -// Extend ItemStore with EventEmitter to add eventing capabilities -var NavigationStore = _.extend({}, EventEmitter.prototype, { - - getGroupIdFromUrl: getGroupIdFromUrl, - - // Emit Change event - emitChange: function() { - this.emit('change'); - }, - - // Add change listener - addChangeListener: function(callback) { - this.on('change', callback); - }, - - // Remove change listener - removeChangeListener: function(callback) { - this.removeListener('change', callback); - }, - - hideCart: function() { - // TODO: figure out how to find this out using Router - var url = document.URL; - var itemIdRegex = /\/(korpa|dostava)/g; - var match = itemIdRegex.exec(url); - if (match) { - return true; - } else { - return false; - } - } - -}); - - - - -// Register callback with AppDispatcher -NavigationStore.dispatchToken = AppDispatcher.register(function(payload) { - var action = payload.action; - - switch (action.actionType) { - - case NavigationConstants.CHANGE_URL: - var router = require('../router'); - setTimeout(function() { - router.transitionTo(action.url); - }, 0); - break; - - default: - return true; - } - - // If action was responded to, emit change event - NavigationStore.emitChange(); - return true; - -}); - -module.exports = NavigationStore; - -},{"../constants/navigationConstants":"/home/senadu/projects/ribica/front-ui/app/constants/navigationConstants.js","../dispatcher/appDispatcher":"/home/senadu/projects/ribica/front-ui/app/dispatcher/appDispatcher.js","../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","../router":"/home/senadu/projects/ribica/front-ui/app/router.js","events":"/home/senadu/projects/ribica/front-ui/node_modules/events/events.js","underscore":"/home/senadu/projects/ribica/front-ui/node_modules/underscore/underscore.js"}],"/home/senadu/projects/ribica/front-ui/app/stores/searchStore.js":[function(require,module,exports){ -var AppDispatcher = require('../dispatcher/appDispatcher'); -var EventEmitter = require('events').EventEmitter; - -var SearchConstants = require('../constants/searchConstants'); -var SearchActions = require('../actions/searchActions'); -var NavigationActions = require('../actions/navigationActions'); - -var ItemSearchCollection = require('../models/itemSearchCollection'); -var globals = require('../globals'); -var _ = require('underscore'); - -var _searchBoxState = { - q: '' -}; - -var _searchResultsState = { - q: '', - items: (new ItemSearchCollection()) -}; - -var handleSearchBoxChange = function(q) { - _searchBoxState.q = q; -}; - - -var handleGetSearchResults = function(q) { - _searchResultsState.q = q; - _searchBoxState.q = ''; - - var searchResults = new ItemSearchCollection(); - searchResults.setQuery(q); - searchResults.fetch({success: function() { - _searchResultsState.items = searchResults; - SearchStore.emit('change'); - }}); -}; - -// Extend ItemStore with EventEmitter to add eventing capabilities -var SearchStore = _.extend({}, EventEmitter.prototype, { - - getSearchBoxState: function() { - return _searchBoxState; - }, - getSearchResultsState: function() { - return _searchResultsState; - }, - // Emit Change event - emitChange: function() { - - this.emit('change'); - }, - - // Add change listener - addChangeListener: function(callback) { - this.on('change', callback); - }, - - // Remove change listener - removeChangeListener: function(callback) { - this.removeListener('change', callback); - } - -}); - - -// Register callback with AppDispatcher -SearchStore.dispatchToken = AppDispatcher.register(function(payload) { - var action = payload.action; - - switch(action.actionType) { - case SearchConstants.SEARCH_BOX_CHANGE: - handleSearchBoxChange(action.q); - break; - - case SearchConstants.GET_SEARCH_RESULTS: - handleGetSearchResults(action.q); - break; - default: - return true; - } - - // If action was responded to, emit change event - SearchStore.emitChange(); - return true; - -}); - -module.exports = SearchStore; - - -},{"../actions/navigationActions":"/home/senadu/projects/ribica/front-ui/app/actions/navigationActions.js","../actions/searchActions":"/home/senadu/projects/ribica/front-ui/app/actions/searchActions.js","../constants/searchConstants":"/home/senadu/projects/ribica/front-ui/app/constants/searchConstants.js","../dispatcher/appDispatcher":"/home/senadu/projects/ribica/front-ui/app/dispatcher/appDispatcher.js","../globals":"/home/senadu/projects/ribica/front-ui/app/globals.js","../models/itemSearchCollection":"/home/senadu/projects/ribica/front-ui/app/models/itemSearchCollection.js","events":"/home/senadu/projects/ribica/front-ui/node_modules/events/events.js","underscore":"/home/senadu/projects/ribica/front-ui/node_modules/underscore/underscore.js"}],"/home/senadu/projects/ribica/front-ui/app/stores/sectionStore.js":[function(require,module,exports){ -var AppDispatcher = require('../dispatcher/appDispatcher'); -var EventEmitter = require('events').EventEmitter; -var SectionCollection = require('../models/sectionCollection'); -var Section = require('../models/section'); -var SectionConstants = require('../constants/sectionConstants'); -var _ = require('underscore'); - -var _sectionDetails = new Section(); -var sectionState = { - sections : [], - hoveredSection : '' -}; - - -var loadSections = function() { - var sections = new SectionCollection(); - sections.fetch({success: function() { - sectionState.sections = sections.models; - // change will be called automatically when - // action is run but we need to emit it again - // when the data arive - // it's a bit "unfluxy" but convenient. - // "true philosophy" would be to run another "data arrived" action - SectionStore.emitChange(); - }}); -}; - -var loadSectionDetails = function(sectionId) { - var section = new Section({id : sectionId}); - section.fetch({ - success: function() { - _sectionDetails = section; - - SectionStore.emitChange(); - } - }); -}; - -var setHovered = function(id) { - sectionState.hoveredSection = id; -} - - -// Extend SectionStore with EventEmitter to add eventing capabilities -var SectionStore = _.extend({}, EventEmitter.prototype, { - - // Return Single Item With Details - getState: function() { - return sectionState; - }, - getSectionDetails: function() { - return _sectionDetails; - }, - // Emit Change event - emitChange: function() { - - this.emit('change'); - }, - - // Add change listener - addChangeListener: function(callback) { - this.on('change', callback); - }, - - // Remove change listener - removeChangeListener: function(callback) { - this.removeListener('change', callback); - } -}); - - -// Register callback with AppDispatcher -AppDispatcher.register(function(payload) { - var action = payload.action; - var text; - - switch(action.actionType) { - - // Respond to SELECT_ITEM action - case SectionConstants.LOAD_SECTIONS: - loadSections(); - break; - - case SectionConstants.SET_SECTION_HOVER: - setHovered(action.section.get('id')); - break; - - case SectionConstants.UNSET_SECTION_HOVER: - setHovered(''); - break; - - case SectionConstants.LOAD_SECTION_DETAILS: - loadSectionDetails(action.sectionId); - break; - - default: - return true; - } - - // If action was responded to, emit change event - SectionStore.emitChange(); - return true; - -}); - -module.exports = SectionStore; - - -},{"../constants/sectionConstants":"/home/senadu/projects/ribica/front-ui/app/constants/sectionConstants.js","../dispatcher/appDispatcher":"/home/senadu/projects/ribica/front-ui/app/dispatcher/appDispatcher.js","../models/section":"/home/senadu/projects/ribica/front-ui/app/models/section.js","../models/sectionCollection":"/home/senadu/projects/ribica/front-ui/app/models/sectionCollection.js","events":"/home/senadu/projects/ribica/front-ui/node_modules/events/events.js","underscore":"/home/senadu/projects/ribica/front-ui/node_modules/underscore/underscore.js"}],"/home/senadu/projects/ribica/front-ui/app/stores/userStore.js":[function(require,module,exports){ -var AppDispatcher = require('../dispatcher/appDispatcher'); -var EventEmitter = require('events').EventEmitter; -var UserConstants = require('../constants/userConstants'); -var _ = require('underscore'); -var CartActions = require('../actions/cartActions'); -var InitializationActions = require('../actions/initializationActions'); -var _registrationState = {}; -var _loginState = {}; - -var handleRegistrationSuccess = function(user) { - _registrationState = { - performed: true, - success: true - }; - - handleLoginSuccess(user); -}; - -var handleRegistrationFailure = function(error) { - _registrationState = { - performed: true, - success: false, - error: error - }; - -}; - -var handleLoginSuccess = function(user) { - _loginState = { - loggedIn: true, - user: user - }; - - refreshCart(); - -}; - -var handleLoginFailure = function(error) { - _loginState = { - loggedIn: false, - error: error - }; - -}; - -var handleCheckLoginArrived = function(user, error) { - if (user) { - _loginState = { - loggedIn: true, - user: user - }; - } else { - _loginState = { - loggedIn: false - }; - } -}; - -var handleLogoutDone = function() { - _registrationState = {}; - _loginState = { - loggedIn: false - } - - refreshCart(); -}; - -var refreshCart = function() { - - setTimeout(function() { - // needed for cart reset - InitializationActions.initialize(); - setTimeout(function() { - // reload the items - CartActions.load(); - }, 0); - }, 0); - -} - -// Extend SectionStore with EventEmitter to add eventing capabilities -var UserStore = _.extend({}, EventEmitter.prototype, { - - getRegistrationState: function() { - //return _categoryDetails; - return _registrationState; - }, - getLoginState: function() { - return _loginState; - }, - // Emit Change event - emitChange: function() { - this.emit('change'); - }, - - // Add change listener - addChangeListener: function(callback) { - this.on('change', callback); - }, - - // Remove change listener - removeChangeListener: function(callback) { - this.removeListener('change', callback); - } -}); - - -// Register callback with AppDispatcher -AppDispatcher.register(function(payload) { - var action = payload.action; - var text; - - switch (action.actionType) { - - - case UserConstants.REGISTRATION_SUCCESS: - handleRegistrationSuccess(action.user); - break; - case UserConstants.REGISTRATION_FAILURE: - handleRegistrationFailure(action.error); - break; - case UserConstants.LOGIN_SUCCESS: - handleLoginSuccess(action.user); - break; - case UserConstants.LOGIN_FAILURE: - handleLoginFailure(action.error); - break; - case UserConstants.CHECK_LOGIN_ARRIVED: - handleCheckLoginArrived(action.user, action.error); - break; - case UserConstants.USER_LOGOUT_DONE: - handleLogoutDone(); - break; - default: - return true; - } - - // If action was responded to, emit change event - UserStore.emitChange(); - return true; - -}); - -module.exports = UserStore; - - -},{"../actions/cartActions":"/home/senadu/projects/ribica/front-ui/app/actions/cartActions.js","../actions/initializationActions":"/home/senadu/projects/ribica/front-ui/app/actions/initializationActions.js","../constants/userConstants":"/home/senadu/projects/ribica/front-ui/app/constants/userConstants.js","../dispatcher/appDispatcher":"/home/senadu/projects/ribica/front-ui/app/dispatcher/appDispatcher.js","events":"/home/senadu/projects/ribica/front-ui/node_modules/events/events.js","underscore":"/home/senadu/projects/ribica/front-ui/node_modules/underscore/underscore.js"}],"/home/senadu/projects/ribica/front-ui/app/utils/validation.js":[function(require,module,exports){ -var _ = require('underscore'); - -var Validations = { - _emailRe: /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/, - isValidEmail: function(value) { - return this._emailRe.test(value); - - }, - isValidRequired: function(value) { - if (value === undefined || value === "") { - return false; - } - return true; - - }, - - safeString: function(item) { - if (!_.isString(item)) { - return ""; - } else { - return item; - } - - } - -}; - -module.exports = Validations; - -},{"underscore":"/home/senadu/projects/ribica/front-ui/node_modules/underscore/underscore.js"}],"/home/senadu/projects/ribica/front-ui/node_modules/Backbone.Mutators/backbone.mutators.js":[function(require,module,exports){ -/*! Backbone.Mutators - v0.4.4 ------------------------------- -Build @ 2015-02-03 -Documentation and Full License Available at: -http://asciidisco.github.com/Backbone.Mutators/index.html -git://github.com/asciidisco/Backbone.Mutators.git -Copyright (c) 2015 Sebastian Golasch - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the - -Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE.*/ -(function (root, factory, undef) { - 'use strict'; - - if (typeof exports === 'object') { - // Node. Does not work with strict CommonJS, but - // only CommonJS-like enviroments that support module.exports, - // like Node. - module.exports = factory(require('underscore'), require('backbone')); - } else if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(['underscore', 'backbone'], function (_, Backbone) { - // Check if we use the AMD branch of Back - _ = _ === undef ? root._ : _; - Backbone = Backbone === undef ? root.Backbone : Backbone; - return (root.returnExportsGlobal = factory(_, Backbone, root)); - }); - } else { - // Browser globals - root.returnExportsGlobal = factory(root._, root.Backbone); - } - -// Usage: -// -// Note: This plugin is UMD compatible, you can use it in node, amd and vanilla js envs -// -// Vanilla JS: -// -// -// -// -// Node: -// var _ = require('underscore'); -// var Backbone = require('backbone'); -// var Mutators = require('backbone.mutators'); -// -// -// AMD: -// define(['underscore', 'backbone', 'backbone.mutators'], function (_, Backbone, Mutators) { -// // insert sample from below -// return User; -// }); -// -// var User = Backbone.Model.extend({ -// mutators: { -// fullname: function () { -// return this.firstname + ' ' + this.lastname; -// } -// }, -// -// defaults: { -// firstname: 'Sebastian', -// lastname: 'Golasch' -// } -// }); -// -// var user = new User(); -// user.get('fullname') // returns 'Sebastian Golasch' -// user.toJSON() // return '{firstname: 'Sebastian', lastname: 'Golasch', fullname: 'Sebastian Golasch'}' - -}(this, function (_, Backbone, root, undef) { - 'use strict'; - - // check if we use the amd branch of backbone and underscore - Backbone = Backbone === undef ? root.Backbone : Backbone; - _ = _ === undef ? root._ : _; - - // extend backbones model prototype with the mutator functionality - var Mutator = function () {}, - oldGet = Backbone.Model.prototype.get, - oldSet = Backbone.Model.prototype.set, - oldToJson = Backbone.Model.prototype.toJSON; - - // This is necessary to ensure that Models declared without the mutators object do not throw and error - Mutator.prototype.mutators = {}; - - // override get functionality to fetch the mutator props - Mutator.prototype.get = function (attr) { - var isMutator = this.mutators !== undef; - - // check if we have a getter mutation - if (isMutator === true && _.isFunction(this.mutators[attr]) === true) { - return this.mutators[attr].call(this); - } - - // check if we have a deeper nested getter mutation - if (isMutator === true && _.isObject(this.mutators[attr]) === true && _.isFunction(this.mutators[attr].get) === true) { - return this.mutators[attr].get.call(this); - } - - return oldGet.call(this, attr); - }; - - // override set functionality to set the mutator props - Mutator.prototype.set = function (key, value, options) { - var isMutator = this.mutators !== undef, - ret = null, - attrs = null; - - ret = oldSet.call(this, key, value, options); - - // seamleassly stolen from backbone core - // check if the setter action is triggered - // using key <-> value or object - if (_.isObject(key) || key === null) { - attrs = key; - options = value; - } else { - attrs = {}; - attrs[key] = value; - } - - // check if we have a deeper nested setter mutation - if (isMutator === true && _.isObject(this.mutators[key]) === true) { - - // check if we need to set a single value - if (_.isFunction(this.mutators[key].set) === true) { - ret = this.mutators[key].set.call(this, key, attrs[key], options, _.bind(oldSet, this)); - } else if(_.isFunction(this.mutators[key])){ - ret = this.mutators[key].call(this, key, attrs[key], options, _.bind(oldSet, this)); - } - } - - if (isMutator === true && _.isObject(attrs)) { - _.each(attrs, _.bind(function (attr, attrKey) { - if (_.isObject(this.mutators[attrKey]) === true) { - // check if we need to set a single value - - var meth = this.mutators[attrKey]; - if(_.isFunction(meth.set)){ - meth = meth.set; - } - - if(_.isFunction(meth)){ - if (options === undef || (_.isObject(options) === true && options.silent !== true && (options.mutators !== undef && options.mutators.silent !== true))) { - this.trigger('mutators:set:' + attrKey); - } - meth.call(this, attrKey, attr, options, _.bind(oldSet, this)); - } - - } - }, this)); - } - - return ret; - }; - - // override toJSON functionality to serialize mutator properties - Mutator.prototype.toJSON = function (options) { - // fetch ye olde values - var attr = oldToJson.call(this), - isSaving, - isTransient; - // iterate over all mutators (if there are some) - _.each(this.mutators, _.bind(function (mutator, name) { - // check if we have some getter mutations - if (_.isObject(this.mutators[name]) === true && _.isFunction(this.mutators[name].get)) { - isSaving = (this.isSaving) ? this.isSaving(options, mutator, name) : _.has(options || {}, 'emulateHTTP'); - isTransient = this.mutators[name].transient; - if (!isSaving || !isTransient) { - attr[name] = _.bind(this.mutators[name].get, this)(); - } - } else if (_.isFunction(this.mutators[name])) { - attr[name] = _.bind(this.mutators[name], this)(); - } - }, this)); - - return attr; - }; - - // override get functionality to get HTML-escaped the mutator props - Mutator.prototype.escape = function (attr){ - var val = this.get(attr); - return _.escape(val == null ? '' : '' + val); - }; - - // extend the models prototype - _.extend(Backbone.Model.prototype, Mutator.prototype); - - // make mutators globally available under the Backbone namespace - Backbone.Mutators = Mutator; - return Mutator; -})); - -},{"backbone":"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js","underscore":"/home/senadu/projects/ribica/front-ui/node_modules/Backbone.Mutators/node_modules/underscore/underscore.js"}],"/home/senadu/projects/ribica/front-ui/node_modules/Backbone.Mutators/node_modules/underscore/underscore.js":[function(require,module,exports){ -// Underscore.js 1.4.4 -// http://underscorejs.org -// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. -// Underscore may be freely distributed under the MIT license. - -(function() { - - // Baseline setup - // -------------- - - // Establish the root object, `window` in the browser, or `global` on the server. - var root = this; - - // Save the previous value of the `_` variable. - var previousUnderscore = root._; - - // Establish the object that gets returned to break out of a loop iteration. - var breaker = {}; - - // Save bytes in the minified (but not gzipped) version: - var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; - - // Create quick reference variables for speed access to core prototypes. - var push = ArrayProto.push, - slice = ArrayProto.slice, - concat = ArrayProto.concat, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - - // All **ECMAScript 5** native function implementations that we hope to use - // are declared here. - var - nativeForEach = ArrayProto.forEach, - nativeMap = ArrayProto.map, - nativeReduce = ArrayProto.reduce, - nativeReduceRight = ArrayProto.reduceRight, - nativeFilter = ArrayProto.filter, - nativeEvery = ArrayProto.every, - nativeSome = ArrayProto.some, - nativeIndexOf = ArrayProto.indexOf, - nativeLastIndexOf = ArrayProto.lastIndexOf, - nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeBind = FuncProto.bind; - - // Create a safe reference to the Underscore object for use below. - var _ = function(obj) { - if (obj instanceof _) return obj; - if (!(this instanceof _)) return new _(obj); - this._wrapped = obj; - }; - - // Export the Underscore object for **Node.js**, with - // backwards-compatibility for the old `require()` API. If we're in - // the browser, add `_` as a global object via a string identifier, - // for Closure Compiler "advanced" mode. - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) { - exports = module.exports = _; - } - exports._ = _; - } else { - root._ = _; - } - - // Current version. - _.VERSION = '1.4.4'; - - // Collection Functions - // -------------------- - - // The cornerstone, an `each` implementation, aka `forEach`. - // Handles objects with the built-in `forEach`, arrays, and raw objects. - // Delegates to **ECMAScript 5**'s native `forEach` if available. - var each = _.each = _.forEach = function(obj, iterator, context) { - if (obj == null) return; - if (nativeForEach && obj.forEach === nativeForEach) { - obj.forEach(iterator, context); - } else if (obj.length === +obj.length) { - for (var i = 0, l = obj.length; i < l; i++) { - if (iterator.call(context, obj[i], i, obj) === breaker) return; - } - } else { - for (var key in obj) { - if (_.has(obj, key)) { - if (iterator.call(context, obj[key], key, obj) === breaker) return; - } - } - } - }; - - // Return the results of applying the iterator to each element. - // Delegates to **ECMAScript 5**'s native `map` if available. - _.map = _.collect = function(obj, iterator, context) { - var results = []; - if (obj == null) return results; - if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); - each(obj, function(value, index, list) { - results[results.length] = iterator.call(context, value, index, list); - }); - return results; - }; - - var reduceError = 'Reduce of empty array with no initial value'; - - // **Reduce** builds up a single result from a list of values, aka `inject`, - // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. - _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { - var initial = arguments.length > 2; - if (obj == null) obj = []; - if (nativeReduce && obj.reduce === nativeReduce) { - if (context) iterator = _.bind(iterator, context); - return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); - } - each(obj, function(value, index, list) { - if (!initial) { - memo = value; - initial = true; - } else { - memo = iterator.call(context, memo, value, index, list); - } - }); - if (!initial) throw new TypeError(reduceError); - return memo; - }; - - // The right-associative version of reduce, also known as `foldr`. - // Delegates to **ECMAScript 5**'s native `reduceRight` if available. - _.reduceRight = _.foldr = function(obj, iterator, memo, context) { - var initial = arguments.length > 2; - if (obj == null) obj = []; - if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { - if (context) iterator = _.bind(iterator, context); - return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); - } - var length = obj.length; - if (length !== +length) { - var keys = _.keys(obj); - length = keys.length; - } - each(obj, function(value, index, list) { - index = keys ? keys[--length] : --length; - if (!initial) { - memo = obj[index]; - initial = true; - } else { - memo = iterator.call(context, memo, obj[index], index, list); - } - }); - if (!initial) throw new TypeError(reduceError); - return memo; - }; - - // Return the first value which passes a truth test. Aliased as `detect`. - _.find = _.detect = function(obj, iterator, context) { - var result; - any(obj, function(value, index, list) { - if (iterator.call(context, value, index, list)) { - result = value; - return true; - } - }); - return result; - }; - - // Return all the elements that pass a truth test. - // Delegates to **ECMAScript 5**'s native `filter` if available. - // Aliased as `select`. - _.filter = _.select = function(obj, iterator, context) { - var results = []; - if (obj == null) return results; - if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); - each(obj, function(value, index, list) { - if (iterator.call(context, value, index, list)) results[results.length] = value; - }); - return results; - }; - - // Return all the elements for which a truth test fails. - _.reject = function(obj, iterator, context) { - return _.filter(obj, function(value, index, list) { - return !iterator.call(context, value, index, list); - }, context); - }; - - // Determine whether all of the elements match a truth test. - // Delegates to **ECMAScript 5**'s native `every` if available. - // Aliased as `all`. - _.every = _.all = function(obj, iterator, context) { - iterator || (iterator = _.identity); - var result = true; - if (obj == null) return result; - if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); - each(obj, function(value, index, list) { - if (!(result = result && iterator.call(context, value, index, list))) return breaker; - }); - return !!result; - }; - - // Determine if at least one element in the object matches a truth test. - // Delegates to **ECMAScript 5**'s native `some` if available. - // Aliased as `any`. - var any = _.some = _.any = function(obj, iterator, context) { - iterator || (iterator = _.identity); - var result = false; - if (obj == null) return result; - if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); - each(obj, function(value, index, list) { - if (result || (result = iterator.call(context, value, index, list))) return breaker; - }); - return !!result; - }; - - // Determine if the array or object contains a given value (using `===`). - // Aliased as `include`. - _.contains = _.include = function(obj, target) { - if (obj == null) return false; - if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; - return any(obj, function(value) { - return value === target; - }); - }; - - // Invoke a method (with arguments) on every item in a collection. - _.invoke = function(obj, method) { - var args = slice.call(arguments, 2); - var isFunc = _.isFunction(method); - return _.map(obj, function(value) { - return (isFunc ? method : value[method]).apply(value, args); - }); - }; - - // Convenience version of a common use case of `map`: fetching a property. - _.pluck = function(obj, key) { - return _.map(obj, function(value){ return value[key]; }); - }; - - // Convenience version of a common use case of `filter`: selecting only objects - // containing specific `key:value` pairs. - _.where = function(obj, attrs, first) { - if (_.isEmpty(attrs)) return first ? null : []; - return _[first ? 'find' : 'filter'](obj, function(value) { - for (var key in attrs) { - if (attrs[key] !== value[key]) return false; - } - return true; - }); - }; - - // Convenience version of a common use case of `find`: getting the first object - // containing specific `key:value` pairs. - _.findWhere = function(obj, attrs) { - return _.where(obj, attrs, true); - }; - - // Return the maximum element or (element-based computation). - // Can't optimize arrays of integers longer than 65,535 elements. - // See: https://bugs.webkit.org/show_bug.cgi?id=80797 - _.max = function(obj, iterator, context) { - if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { - return Math.max.apply(Math, obj); - } - if (!iterator && _.isEmpty(obj)) return -Infinity; - var result = {computed : -Infinity, value: -Infinity}; - each(obj, function(value, index, list) { - var computed = iterator ? iterator.call(context, value, index, list) : value; - computed >= result.computed && (result = {value : value, computed : computed}); - }); - return result.value; - }; - - // Return the minimum element (or element-based computation). - _.min = function(obj, iterator, context) { - if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { - return Math.min.apply(Math, obj); - } - if (!iterator && _.isEmpty(obj)) return Infinity; - var result = {computed : Infinity, value: Infinity}; - each(obj, function(value, index, list) { - var computed = iterator ? iterator.call(context, value, index, list) : value; - computed < result.computed && (result = {value : value, computed : computed}); - }); - return result.value; - }; - - // Shuffle an array. - _.shuffle = function(obj) { - var rand; - var index = 0; - var shuffled = []; - each(obj, function(value) { - rand = _.random(index++); - shuffled[index - 1] = shuffled[rand]; - shuffled[rand] = value; - }); - return shuffled; - }; - - // An internal function to generate lookup iterators. - var lookupIterator = function(value) { - return _.isFunction(value) ? value : function(obj){ return obj[value]; }; - }; - - // Sort the object's values by a criterion produced by an iterator. - _.sortBy = function(obj, value, context) { - var iterator = lookupIterator(value); - return _.pluck(_.map(obj, function(value, index, list) { - return { - value : value, - index : index, - criteria : iterator.call(context, value, index, list) - }; - }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; - } - return left.index < right.index ? -1 : 1; - }), 'value'); - }; - - // An internal function used for aggregate "group by" operations. - var group = function(obj, value, context, behavior) { - var result = {}; - var iterator = lookupIterator(value || _.identity); - each(obj, function(value, index) { - var key = iterator.call(context, value, index, obj); - behavior(result, key, value); - }); - return result; - }; - - // Groups the object's values by a criterion. Pass either a string attribute - // to group by, or a function that returns the criterion. - _.groupBy = function(obj, value, context) { - return group(obj, value, context, function(result, key, value) { - (_.has(result, key) ? result[key] : (result[key] = [])).push(value); - }); - }; - - // Counts instances of an object that group by a certain criterion. Pass - // either a string attribute to count by, or a function that returns the - // criterion. - _.countBy = function(obj, value, context) { - return group(obj, value, context, function(result, key) { - if (!_.has(result, key)) result[key] = 0; - result[key]++; - }); - }; - - // Use a comparator function to figure out the smallest index at which - // an object should be inserted so as to maintain order. Uses binary search. - _.sortedIndex = function(array, obj, iterator, context) { - iterator = iterator == null ? _.identity : lookupIterator(iterator); - var value = iterator.call(context, obj); - var low = 0, high = array.length; - while (low < high) { - var mid = (low + high) >>> 1; - iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid; - } - return low; - }; - - // Safely convert anything iterable into a real, live array. - _.toArray = function(obj) { - if (!obj) return []; - if (_.isArray(obj)) return slice.call(obj); - if (obj.length === +obj.length) return _.map(obj, _.identity); - return _.values(obj); - }; - - // Return the number of elements in an object. - _.size = function(obj) { - if (obj == null) return 0; - return (obj.length === +obj.length) ? obj.length : _.keys(obj).length; - }; - - // Array Functions - // --------------- - - // Get the first element of an array. Passing **n** will return the first N - // values in the array. Aliased as `head` and `take`. The **guard** check - // allows it to work with `_.map`. - _.first = _.head = _.take = function(array, n, guard) { - if (array == null) return void 0; - return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; - }; - - // Returns everything but the last entry of the array. Especially useful on - // the arguments object. Passing **n** will return all the values in - // the array, excluding the last N. The **guard** check allows it to work with - // `_.map`. - _.initial = function(array, n, guard) { - return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); - }; - - // Get the last element of an array. Passing **n** will return the last N - // values in the array. The **guard** check allows it to work with `_.map`. - _.last = function(array, n, guard) { - if (array == null) return void 0; - if ((n != null) && !guard) { - return slice.call(array, Math.max(array.length - n, 0)); - } else { - return array[array.length - 1]; - } - }; - - // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. - // Especially useful on the arguments object. Passing an **n** will return - // the rest N values in the array. The **guard** - // check allows it to work with `_.map`. - _.rest = _.tail = _.drop = function(array, n, guard) { - return slice.call(array, (n == null) || guard ? 1 : n); - }; - - // Trim out all falsy values from an array. - _.compact = function(array) { - return _.filter(array, _.identity); - }; - - // Internal implementation of a recursive `flatten` function. - var flatten = function(input, shallow, output) { - each(input, function(value) { - if (_.isArray(value)) { - shallow ? push.apply(output, value) : flatten(value, shallow, output); - } else { - output.push(value); - } - }); - return output; - }; - - // Return a completely flattened version of an array. - _.flatten = function(array, shallow) { - return flatten(array, shallow, []); - }; - - // Return a version of the array that does not contain the specified value(s). - _.without = function(array) { - return _.difference(array, slice.call(arguments, 1)); - }; - - // Produce a duplicate-free version of the array. If the array has already - // been sorted, you have the option of using a faster algorithm. - // Aliased as `unique`. - _.uniq = _.unique = function(array, isSorted, iterator, context) { - if (_.isFunction(isSorted)) { - context = iterator; - iterator = isSorted; - isSorted = false; - } - var initial = iterator ? _.map(array, iterator, context) : array; - var results = []; - var seen = []; - each(initial, function(value, index) { - if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) { - seen.push(value); - results.push(array[index]); - } - }); - return results; - }; - - // Produce an array that contains the union: each distinct element from all of - // the passed-in arrays. - _.union = function() { - return _.uniq(concat.apply(ArrayProto, arguments)); - }; - - // Produce an array that contains every item shared between all the - // passed-in arrays. - _.intersection = function(array) { - var rest = slice.call(arguments, 1); - return _.filter(_.uniq(array), function(item) { - return _.every(rest, function(other) { - return _.indexOf(other, item) >= 0; - }); - }); - }; - - // Take the difference between one array and a number of other arrays. - // Only the elements present in just the first array will remain. - _.difference = function(array) { - var rest = concat.apply(ArrayProto, slice.call(arguments, 1)); - return _.filter(array, function(value){ return !_.contains(rest, value); }); - }; - - // Zip together multiple lists into a single array -- elements that share - // an index go together. - _.zip = function() { - var args = slice.call(arguments); - var length = _.max(_.pluck(args, 'length')); - var results = new Array(length); - for (var i = 0; i < length; i++) { - results[i] = _.pluck(args, "" + i); - } - return results; - }; - - // Converts lists into objects. Pass either a single array of `[key, value]` - // pairs, or two parallel arrays of the same length -- one of keys, and one of - // the corresponding values. - _.object = function(list, values) { - if (list == null) return {}; - var result = {}; - for (var i = 0, l = list.length; i < l; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; - }; - - // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), - // we need this function. Return the position of the first occurrence of an - // item in an array, or -1 if the item is not included in the array. - // Delegates to **ECMAScript 5**'s native `indexOf` if available. - // If the array is large and already in sort order, pass `true` - // for **isSorted** to use binary search. - _.indexOf = function(array, item, isSorted) { - if (array == null) return -1; - var i = 0, l = array.length; - if (isSorted) { - if (typeof isSorted == 'number') { - i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted); - } else { - i = _.sortedIndex(array, item); - return array[i] === item ? i : -1; - } - } - if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted); - for (; i < l; i++) if (array[i] === item) return i; - return -1; - }; - - // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. - _.lastIndexOf = function(array, item, from) { - if (array == null) return -1; - var hasIndex = from != null; - if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) { - return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item); - } - var i = (hasIndex ? from : array.length); - while (i--) if (array[i] === item) return i; - return -1; - }; - - // Generate an integer Array containing an arithmetic progression. A port of - // the native Python `range()` function. See - // [the Python documentation](http://docs.python.org/library/functions.html#range). - _.range = function(start, stop, step) { - if (arguments.length <= 1) { - stop = start || 0; - start = 0; - } - step = arguments[2] || 1; - - var len = Math.max(Math.ceil((stop - start) / step), 0); - var idx = 0; - var range = new Array(len); - - while(idx < len) { - range[idx++] = start; - start += step; - } - - return range; - }; - - // Function (ahem) Functions - // ------------------ - - // Create a function bound to a given object (assigning `this`, and arguments, - // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if - // available. - _.bind = function(func, context) { - if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); - var args = slice.call(arguments, 2); - return function() { - return func.apply(context, args.concat(slice.call(arguments))); - }; - }; - - // Partially apply a function by creating a version that has had some of its - // arguments pre-filled, without changing its dynamic `this` context. - _.partial = function(func) { - var args = slice.call(arguments, 1); - return function() { - return func.apply(this, args.concat(slice.call(arguments))); - }; - }; - - // Bind all of an object's methods to that object. Useful for ensuring that - // all callbacks defined on an object belong to it. - _.bindAll = function(obj) { - var funcs = slice.call(arguments, 1); - if (funcs.length === 0) funcs = _.functions(obj); - each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); - return obj; - }; - - // Memoize an expensive function by storing its results. - _.memoize = function(func, hasher) { - var memo = {}; - hasher || (hasher = _.identity); - return function() { - var key = hasher.apply(this, arguments); - return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); - }; - }; - - // Delays a function for the given number of milliseconds, and then calls - // it with the arguments supplied. - _.delay = function(func, wait) { - var args = slice.call(arguments, 2); - return setTimeout(function(){ return func.apply(null, args); }, wait); - }; - - // Defers a function, scheduling it to run after the current call stack has - // cleared. - _.defer = function(func) { - return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); - }; - - // Returns a function, that, when invoked, will only be triggered at most once - // during a given window of time. - _.throttle = function(func, wait) { - var context, args, timeout, result; - var previous = 0; - var later = function() { - previous = new Date; - timeout = null; - result = func.apply(context, args); - }; - return function() { - var now = new Date; - var remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0) { - clearTimeout(timeout); - timeout = null; - previous = now; - result = func.apply(context, args); - } else if (!timeout) { - timeout = setTimeout(later, remaining); - } - return result; - }; - }; - - // Returns a function, that, as long as it continues to be invoked, will not - // be triggered. The function will be called after it stops being called for - // N milliseconds. If `immediate` is passed, trigger the function on the - // leading edge, instead of the trailing. - _.debounce = function(func, wait, immediate) { - var timeout, result; - return function() { - var context = this, args = arguments; - var later = function() { - timeout = null; - if (!immediate) result = func.apply(context, args); - }; - var callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - if (callNow) result = func.apply(context, args); - return result; - }; - }; - - // Returns a function that will be executed at most one time, no matter how - // often you call it. Useful for lazy initialization. - _.once = function(func) { - var ran = false, memo; - return function() { - if (ran) return memo; - ran = true; - memo = func.apply(this, arguments); - func = null; - return memo; - }; - }; - - // Returns the first function passed as an argument to the second, - // allowing you to adjust arguments, run code before and after, and - // conditionally execute the original function. - _.wrap = function(func, wrapper) { - return function() { - var args = [func]; - push.apply(args, arguments); - return wrapper.apply(this, args); - }; - }; - - // Returns a function that is the composition of a list of functions, each - // consuming the return value of the function that follows. - _.compose = function() { - var funcs = arguments; - return function() { - var args = arguments; - for (var i = funcs.length - 1; i >= 0; i--) { - args = [funcs[i].apply(this, args)]; - } - return args[0]; - }; - }; - - // Returns a function that will only be executed after being called N times. - _.after = function(times, func) { - if (times <= 0) return func(); - return function() { - if (--times < 1) { - return func.apply(this, arguments); - } - }; - }; - - // Object Functions - // ---------------- - - // Retrieve the names of an object's properties. - // Delegates to **ECMAScript 5**'s native `Object.keys` - _.keys = nativeKeys || function(obj) { - if (obj !== Object(obj)) throw new TypeError('Invalid object'); - var keys = []; - for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key; - return keys; - }; - - // Retrieve the values of an object's properties. - _.values = function(obj) { - var values = []; - for (var key in obj) if (_.has(obj, key)) values.push(obj[key]); - return values; - }; - - // Convert an object into a list of `[key, value]` pairs. - _.pairs = function(obj) { - var pairs = []; - for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]); - return pairs; - }; - - // Invert the keys and values of an object. The values must be serializable. - _.invert = function(obj) { - var result = {}; - for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key; - return result; - }; - - // Return a sorted list of the function names available on the object. - // Aliased as `methods` - _.functions = _.methods = function(obj) { - var names = []; - for (var key in obj) { - if (_.isFunction(obj[key])) names.push(key); - } - return names.sort(); - }; - - // Extend a given object with all the properties in passed-in object(s). - _.extend = function(obj) { - each(slice.call(arguments, 1), function(source) { - if (source) { - for (var prop in source) { - obj[prop] = source[prop]; - } - } - }); - return obj; - }; - - // Return a copy of the object only containing the whitelisted properties. - _.pick = function(obj) { - var copy = {}; - var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); - each(keys, function(key) { - if (key in obj) copy[key] = obj[key]; - }); - return copy; - }; - - // Return a copy of the object without the blacklisted properties. - _.omit = function(obj) { - var copy = {}; - var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); - for (var key in obj) { - if (!_.contains(keys, key)) copy[key] = obj[key]; - } - return copy; - }; - - // Fill in a given object with default properties. - _.defaults = function(obj) { - each(slice.call(arguments, 1), function(source) { - if (source) { - for (var prop in source) { - if (obj[prop] == null) obj[prop] = source[prop]; - } - } - }); - return obj; - }; - - // Create a (shallow-cloned) duplicate of an object. - _.clone = function(obj) { - if (!_.isObject(obj)) return obj; - return _.isArray(obj) ? obj.slice() : _.extend({}, obj); - }; - - // Invokes interceptor with the obj, and then returns obj. - // The primary purpose of this method is to "tap into" a method chain, in - // order to perform operations on intermediate results within the chain. - _.tap = function(obj, interceptor) { - interceptor(obj); - return obj; - }; - - // Internal recursive comparison function for `isEqual`. - var eq = function(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal. - if (a === b) return a !== 0 || 1 / a == 1 / b; - // A strict comparison is necessary because `null == undefined`. - if (a == null || b == null) return a === b; - // Unwrap any wrapped objects. - if (a instanceof _) a = a._wrapped; - if (b instanceof _) b = b._wrapped; - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className != toString.call(b)) return false; - switch (className) { - // Strings, numbers, dates, and booleans are compared by value. - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return a == String(b); - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for - // other numeric values. - return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a == +b; - // RegExps are compared by their source patterns and flags. - case '[object RegExp]': - return a.source == b.source && - a.global == b.global && - a.multiline == b.multiline && - a.ignoreCase == b.ignoreCase; - } - if (typeof a != 'object' || typeof b != 'object') return false; - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] == a) return bStack[length] == b; - } - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - var size = 0, result = true; - // Recursively compare objects and arrays. - if (className == '[object Array]') { - // Compare array lengths to determine if a deep comparison is necessary. - size = a.length; - result = size == b.length; - if (result) { - // Deep compare the contents, ignoring non-numeric properties. - while (size--) { - if (!(result = eq(a[size], b[size], aStack, bStack))) break; - } - } - } else { - // Objects with different constructors are not equivalent, but `Object`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) && - _.isFunction(bCtor) && (bCtor instanceof bCtor))) { - return false; - } - // Deep compare objects. - for (var key in a) { - if (_.has(a, key)) { - // Count the expected number of properties. - size++; - // Deep compare each member. - if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; - } - } - // Ensure that both objects contain the same number of properties. - if (result) { - for (key in b) { - if (_.has(b, key) && !(size--)) break; - } - result = !size; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return result; - }; - - // Perform a deep comparison to check if two objects are equal. - _.isEqual = function(a, b) { - return eq(a, b, [], []); - }; - - // Is a given array, string, or object empty? - // An "empty" object has no enumerable own-properties. - _.isEmpty = function(obj) { - if (obj == null) return true; - if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; - for (var key in obj) if (_.has(obj, key)) return false; - return true; - }; - - // Is a given value a DOM element? - _.isElement = function(obj) { - return !!(obj && obj.nodeType === 1); - }; - - // Is a given value an array? - // Delegates to ECMA5's native Array.isArray - _.isArray = nativeIsArray || function(obj) { - return toString.call(obj) == '[object Array]'; - }; - - // Is a given variable an object? - _.isObject = function(obj) { - return obj === Object(obj); - }; - - // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. - each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { - _['is' + name] = function(obj) { - return toString.call(obj) == '[object ' + name + ']'; - }; - }); - - // Define a fallback version of the method in browsers (ahem, IE), where - // there isn't any inspectable "Arguments" type. - if (!_.isArguments(arguments)) { - _.isArguments = function(obj) { - return !!(obj && _.has(obj, 'callee')); - }; - } - - // Optimize `isFunction` if appropriate. - if (typeof (/./) !== 'function') { - _.isFunction = function(obj) { - return typeof obj === 'function'; - }; - } - - // Is a given object a finite number? - _.isFinite = function(obj) { - return isFinite(obj) && !isNaN(parseFloat(obj)); - }; - - // Is the given value `NaN`? (NaN is the only number which does not equal itself). - _.isNaN = function(obj) { - return _.isNumber(obj) && obj != +obj; - }; - - // Is a given value a boolean? - _.isBoolean = function(obj) { - return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; - }; - - // Is a given value equal to null? - _.isNull = function(obj) { - return obj === null; - }; - - // Is a given variable undefined? - _.isUndefined = function(obj) { - return obj === void 0; - }; - - // Shortcut function for checking if an object has a given property directly - // on itself (in other words, not on a prototype). - _.has = function(obj, key) { - return hasOwnProperty.call(obj, key); - }; - - // Utility Functions - // ----------------- - - // Run Underscore.js in *noConflict* mode, returning the `_` variable to its - // previous owner. Returns a reference to the Underscore object. - _.noConflict = function() { - root._ = previousUnderscore; - return this; - }; - - // Keep the identity function around for default iterators. - _.identity = function(value) { - return value; - }; - - // Run a function **n** times. - _.times = function(n, iterator, context) { - var accum = Array(n); - for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i); - return accum; - }; - - // Return a random integer between min and max (inclusive). - _.random = function(min, max) { - if (max == null) { - max = min; - min = 0; - } - return min + Math.floor(Math.random() * (max - min + 1)); - }; - - // List of HTML entities for escaping. - var entityMap = { - escape: { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '/': '/' - } - }; - entityMap.unescape = _.invert(entityMap.escape); - - // Regexes containing the keys and values listed immediately above. - var entityRegexes = { - escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'), - unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g') - }; - - // Functions for escaping and unescaping strings to/from HTML interpolation. - _.each(['escape', 'unescape'], function(method) { - _[method] = function(string) { - if (string == null) return ''; - return ('' + string).replace(entityRegexes[method], function(match) { - return entityMap[method][match]; - }); - }; - }); - - // If the value of the named property is a function then invoke it; - // otherwise, return it. - _.result = function(object, property) { - if (object == null) return null; - var value = object[property]; - return _.isFunction(value) ? value.call(object) : value; - }; - - // Add your own custom functions to the Underscore object. - _.mixin = function(obj) { - each(_.functions(obj), function(name){ - var func = _[name] = obj[name]; - _.prototype[name] = function() { - var args = [this._wrapped]; - push.apply(args, arguments); - return result.call(this, func.apply(_, args)); - }; - }); - }; - - // Generate a unique integer id (unique within the entire client session). - // Useful for temporary DOM ids. - var idCounter = 0; - _.uniqueId = function(prefix) { - var id = ++idCounter + ''; - return prefix ? prefix + id : id; - }; - - // By default, Underscore uses ERB-style template delimiters, change the - // following template settings to use alternative delimiters. - _.templateSettings = { - evaluate : /<%([\s\S]+?)%>/g, - interpolate : /<%=([\s\S]+?)%>/g, - escape : /<%-([\s\S]+?)%>/g - }; - - // When customizing `templateSettings`, if you don't want to define an - // interpolation, evaluation or escaping regex, we need one that is - // guaranteed not to match. - var noMatch = /(.)^/; - - // Certain characters need to be escaped so that they can be put into a - // string literal. - var escapes = { - "'": "'", - '\\': '\\', - '\r': 'r', - '\n': 'n', - '\t': 't', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; - - // JavaScript micro-templating, similar to John Resig's implementation. - // Underscore templating handles arbitrary delimiters, preserves whitespace, - // and correctly escapes quotes within interpolated code. - _.template = function(text, data, settings) { - var render; - settings = _.defaults({}, settings, _.templateSettings); - - // Combine delimiters into one regular expression via alternation. - var matcher = new RegExp([ - (settings.escape || noMatch).source, - (settings.interpolate || noMatch).source, - (settings.evaluate || noMatch).source - ].join('|') + '|$', 'g'); - - // Compile the template source, escaping string literals appropriately. - var index = 0; - var source = "__p+='"; - text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { - source += text.slice(index, offset) - .replace(escaper, function(match) { return '\\' + escapes[match]; }); - - if (escape) { - source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; - } - if (interpolate) { - source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; - } - if (evaluate) { - source += "';\n" + evaluate + "\n__p+='"; - } - index = offset + match.length; - return match; - }); - source += "';\n"; - - // If a variable is not specified, place data values in local scope. - if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; - - source = "var __t,__p='',__j=Array.prototype.join," + - "print=function(){__p+=__j.call(arguments,'');};\n" + - source + "return __p;\n"; - - try { - render = new Function(settings.variable || 'obj', '_', source); - } catch (e) { - e.source = source; - throw e; - } - - if (data) return render(data, _); - var template = function(data) { - return render.call(this, data, _); - }; - - // Provide the compiled function source as a convenience for precompilation. - template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; - - return template; - }; - - // Add a "chain" function, which will delegate to the wrapper. - _.chain = function(obj) { - return _(obj).chain(); - }; - - // OOP - // --------------- - // If Underscore is called as a function, it returns a wrapped object that - // can be used OO-style. This wrapper holds altered versions of all the - // underscore functions. Wrapped objects may be chained. - - // Helper function to continue chaining intermediate results. - var result = function(obj) { - return this._chain ? _(obj).chain() : obj; - }; - - // Add all of the Underscore functions to the wrapper object. - _.mixin(_); - - // Add all mutator Array functions to the wrapper. - each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - var obj = this._wrapped; - method.apply(obj, arguments); - if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0]; - return result.call(this, obj); - }; - }); - - // Add all accessor Array functions to the wrapper. - each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - return result.call(this, method.apply(this._wrapped, arguments)); - }; - }); - - _.extend(_.prototype, { - - // Start chaining a wrapped Underscore object. - chain: function() { - this._chain = true; - return this; - }, - - // Extracts the result from a wrapped and chained object. - value: function() { - return this._wrapped; - } - - }); - -}).call(this); - -},{}],"/home/senadu/projects/ribica/front-ui/node_modules/backbone/backbone.js":[function(require,module,exports){ -// Backbone.js 1.1.2 - -// (c) 2010-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors -// Backbone may be freely distributed under the MIT license. -// For all details and documentation: -// http://backbonejs.org - -(function(root, factory) { - - // Set up Backbone appropriately for the environment. Start with AMD. - if (typeof define === 'function' && define.amd) { - define(['underscore', 'jquery', 'exports'], function(_, $, exports) { - // Export global even in AMD case in case this script is loaded with - // others that may still expect a global Backbone. - root.Backbone = factory(root, exports, _, $); - }); - - // Next for Node.js or CommonJS. jQuery may not be needed as a module. - } else if (typeof exports !== 'undefined') { - var _ = require('underscore'); - factory(root, exports, _); - - // Finally, as a browser global. - } else { - root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$)); - } - -}(this, function(root, Backbone, _, $) { - - // Initial Setup - // ------------- - - // Save the previous value of the `Backbone` variable, so that it can be - // restored later on, if `noConflict` is used. - var previousBackbone = root.Backbone; - - // Create local references to array methods we'll want to use later. - var array = []; - var push = array.push; - var slice = array.slice; - var splice = array.splice; - - // Current version of the library. Keep in sync with `package.json`. - Backbone.VERSION = '1.1.2'; - - // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns - // the `$` variable. - Backbone.$ = $; - - // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable - // to its previous owner. Returns a reference to this Backbone object. - Backbone.noConflict = function() { - root.Backbone = previousBackbone; - return this; - }; - - // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option - // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and - // set a `X-Http-Method-Override` header. - Backbone.emulateHTTP = false; - - // Turn on `emulateJSON` to support legacy servers that can't deal with direct - // `application/json` requests ... will encode the body as - // `application/x-www-form-urlencoded` instead and will send the model in a - // form param named `model`. - Backbone.emulateJSON = false; - - // Backbone.Events - // --------------- - - // A module that can be mixed in to *any object* in order to provide it with - // custom events. You may bind with `on` or remove with `off` callback - // functions to an event; `trigger`-ing an event fires all callbacks in - // succession. - // - // var object = {}; - // _.extend(object, Backbone.Events); - // object.on('expand', function(){ alert('expanded'); }); - // object.trigger('expand'); - // - var Events = Backbone.Events = { - - // Bind an event to a `callback` function. Passing `"all"` will bind - // the callback to all events fired. - on: function(name, callback, context) { - if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this; - this._events || (this._events = {}); - var events = this._events[name] || (this._events[name] = []); - events.push({callback: callback, context: context, ctx: context || this}); - return this; - }, - - // Bind an event to only be triggered a single time. After the first time - // the callback is invoked, it will be removed. - once: function(name, callback, context) { - if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this; - var self = this; - var once = _.once(function() { - self.off(name, once); - callback.apply(this, arguments); - }); - once._callback = callback; - return this.on(name, once, context); - }, - - // Remove one or many callbacks. If `context` is null, removes all - // callbacks with that function. If `callback` is null, removes all - // callbacks for the event. If `name` is null, removes all bound - // callbacks for all events. - off: function(name, callback, context) { - var retain, ev, events, names, i, l, j, k; - if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this; - if (!name && !callback && !context) { - this._events = void 0; - return this; - } - names = name ? [name] : _.keys(this._events); - for (i = 0, l = names.length; i < l; i++) { - name = names[i]; - if (events = this._events[name]) { - this._events[name] = retain = []; - if (callback || context) { - for (j = 0, k = events.length; j < k; j++) { - ev = events[j]; - if ((callback && callback !== ev.callback && callback !== ev.callback._callback) || - (context && context !== ev.context)) { - retain.push(ev); - } - } - } - if (!retain.length) delete this._events[name]; - } - } - - return this; - }, - - // Trigger one or many events, firing all bound callbacks. Callbacks are - // passed the same arguments as `trigger` is, apart from the event name - // (unless you're listening on `"all"`, which will cause your callback to - // receive the true name of the event as the first argument). - trigger: function(name) { - if (!this._events) return this; - var args = slice.call(arguments, 1); - if (!eventsApi(this, 'trigger', name, args)) return this; - var events = this._events[name]; - var allEvents = this._events.all; - if (events) triggerEvents(events, args); - if (allEvents) triggerEvents(allEvents, arguments); - return this; - }, - - // Tell this object to stop listening to either specific events ... or - // to every object it's currently listening to. - stopListening: function(obj, name, callback) { - var listeningTo = this._listeningTo; - if (!listeningTo) return this; - var remove = !name && !callback; - if (!callback && typeof name === 'object') callback = this; - if (obj) (listeningTo = {})[obj._listenId] = obj; - for (var id in listeningTo) { - obj = listeningTo[id]; - obj.off(name, callback, this); - if (remove || _.isEmpty(obj._events)) delete this._listeningTo[id]; - } - return this; - } - - }; - - // Regular expression used to split event strings. - var eventSplitter = /\s+/; - - // Implement fancy features of the Events API such as multiple event - // names `"change blur"` and jQuery-style event maps `{change: action}` - // in terms of the existing API. - var eventsApi = function(obj, action, name, rest) { - if (!name) return true; - - // Handle event maps. - if (typeof name === 'object') { - for (var key in name) { - obj[action].apply(obj, [key, name[key]].concat(rest)); - } - return false; - } - - // Handle space separated event names. - if (eventSplitter.test(name)) { - var names = name.split(eventSplitter); - for (var i = 0, l = names.length; i < l; i++) { - obj[action].apply(obj, [names[i]].concat(rest)); - } - return false; - } - - return true; - }; - - // A difficult-to-believe, but optimized internal dispatch function for - // triggering events. Tries to keep the usual cases speedy (most internal - // Backbone events have 3 arguments). - var triggerEvents = function(events, args) { - var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2]; - switch (args.length) { - case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return; - case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return; - case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return; - case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return; - default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return; - } - }; - - var listenMethods = {listenTo: 'on', listenToOnce: 'once'}; - - // Inversion-of-control versions of `on` and `once`. Tell *this* object to - // listen to an event in another object ... keeping track of what it's - // listening to. - _.each(listenMethods, function(implementation, method) { - Events[method] = function(obj, name, callback) { - var listeningTo = this._listeningTo || (this._listeningTo = {}); - var id = obj._listenId || (obj._listenId = _.uniqueId('l')); - listeningTo[id] = obj; - if (!callback && typeof name === 'object') callback = this; - obj[implementation](name, callback, this); - return this; - }; - }); - - // Aliases for backwards compatibility. - Events.bind = Events.on; - Events.unbind = Events.off; - - // Allow the `Backbone` object to serve as a global event bus, for folks who - // want global "pubsub" in a convenient place. - _.extend(Backbone, Events); - - // Backbone.Model - // -------------- - - // Backbone **Models** are the basic data object in the framework -- - // frequently representing a row in a table in a database on your server. - // A discrete chunk of data and a bunch of useful, related methods for - // performing computations and transformations on that data. - - // Create a new model with the specified attributes. A client id (`cid`) - // is automatically generated and assigned for you. - var Model = Backbone.Model = function(attributes, options) { - var attrs = attributes || {}; - options || (options = {}); - this.cid = _.uniqueId('c'); - this.attributes = {}; - if (options.collection) this.collection = options.collection; - if (options.parse) attrs = this.parse(attrs, options) || {}; - attrs = _.defaults({}, attrs, _.result(this, 'defaults')); - this.set(attrs, options); - this.changed = {}; - this.initialize.apply(this, arguments); - }; - - // Attach all inheritable methods to the Model prototype. - _.extend(Model.prototype, Events, { - - // A hash of attributes whose current and previous value differ. - changed: null, - - // The value returned during the last failed validation. - validationError: null, - - // The default name for the JSON `id` attribute is `"id"`. MongoDB and - // CouchDB users may want to set this to `"_id"`. - idAttribute: 'id', - - // Initialize is an empty function by default. Override it with your own - // initialization logic. - initialize: function(){}, - - // Return a copy of the model's `attributes` object. - toJSON: function(options) { - return _.clone(this.attributes); - }, - - // Proxy `Backbone.sync` by default -- but override this if you need - // custom syncing semantics for *this* particular model. - sync: function() { - return Backbone.sync.apply(this, arguments); - }, - - // Get the value of an attribute. - get: function(attr) { - return this.attributes[attr]; - }, - - // Get the HTML-escaped value of an attribute. - escape: function(attr) { - return _.escape(this.get(attr)); - }, - - // Returns `true` if the attribute contains a value that is not null - // or undefined. - has: function(attr) { - return this.get(attr) != null; - }, - - // Set a hash of model attributes on the object, firing `"change"`. This is - // the core primitive operation of a model, updating the data and notifying - // anyone who needs to know about the change in state. The heart of the beast. - set: function(key, val, options) { - var attr, attrs, unset, changes, silent, changing, prev, current; - if (key == null) return this; - - // Handle both `"key", value` and `{key: value}` -style arguments. - if (typeof key === 'object') { - attrs = key; - options = val; - } else { - (attrs = {})[key] = val; - } - - options || (options = {}); - - // Run validation. - if (!this._validate(attrs, options)) return false; - - // Extract attributes and options. - unset = options.unset; - silent = options.silent; - changes = []; - changing = this._changing; - this._changing = true; - - if (!changing) { - this._previousAttributes = _.clone(this.attributes); - this.changed = {}; - } - current = this.attributes, prev = this._previousAttributes; - - // Check for changes of `id`. - if (this.idAttribute in attrs) this.id = attrs[this.idAttribute]; - - // For each `set` attribute, update or delete the current value. - for (attr in attrs) { - val = attrs[attr]; - if (!_.isEqual(current[attr], val)) changes.push(attr); - if (!_.isEqual(prev[attr], val)) { - this.changed[attr] = val; - } else { - delete this.changed[attr]; - } - unset ? delete current[attr] : current[attr] = val; - } - - // Trigger all relevant attribute changes. - if (!silent) { - if (changes.length) this._pending = options; - for (var i = 0, l = changes.length; i < l; i++) { - this.trigger('change:' + changes[i], this, current[changes[i]], options); - } - } - - // You might be wondering why there's a `while` loop here. Changes can - // be recursively nested within `"change"` events. - if (changing) return this; - if (!silent) { - while (this._pending) { - options = this._pending; - this._pending = false; - this.trigger('change', this, options); - } - } - this._pending = false; - this._changing = false; - return this; - }, - - // Remove an attribute from the model, firing `"change"`. `unset` is a noop - // if the attribute doesn't exist. - unset: function(attr, options) { - return this.set(attr, void 0, _.extend({}, options, {unset: true})); - }, - - // Clear all attributes on the model, firing `"change"`. - clear: function(options) { - var attrs = {}; - for (var key in this.attributes) attrs[key] = void 0; - return this.set(attrs, _.extend({}, options, {unset: true})); - }, - - // Determine if the model has changed since the last `"change"` event. - // If you specify an attribute name, determine if that attribute has changed. - hasChanged: function(attr) { - if (attr == null) return !_.isEmpty(this.changed); - return _.has(this.changed, attr); - }, - - // Return an object containing all the attributes that have changed, or - // false if there are no changed attributes. Useful for determining what - // parts of a view need to be updated and/or what attributes need to be - // persisted to the server. Unset attributes will be set to undefined. - // You can also pass an attributes object to diff against the model, - // determining if there *would be* a change. - changedAttributes: function(diff) { - if (!diff) return this.hasChanged() ? _.clone(this.changed) : false; - var val, changed = false; - var old = this._changing ? this._previousAttributes : this.attributes; - for (var attr in diff) { - if (_.isEqual(old[attr], (val = diff[attr]))) continue; - (changed || (changed = {}))[attr] = val; - } - return changed; - }, - - // Get the previous value of an attribute, recorded at the time the last - // `"change"` event was fired. - previous: function(attr) { - if (attr == null || !this._previousAttributes) return null; - return this._previousAttributes[attr]; - }, - - // Get all of the attributes of the model at the time of the previous - // `"change"` event. - previousAttributes: function() { - return _.clone(this._previousAttributes); - }, - - // Fetch the model from the server. If the server's representation of the - // model differs from its current attributes, they will be overridden, - // triggering a `"change"` event. - fetch: function(options) { - options = options ? _.clone(options) : {}; - if (options.parse === void 0) options.parse = true; - var model = this; - var success = options.success; - options.success = function(resp) { - if (!model.set(model.parse(resp, options), options)) return false; - if (success) success(model, resp, options); - model.trigger('sync', model, resp, options); - }; - wrapError(this, options); - return this.sync('read', this, options); - }, - - // Set a hash of model attributes, and sync the model to the server. - // If the server returns an attributes hash that differs, the model's - // state will be `set` again. - save: function(key, val, options) { - var attrs, method, xhr, attributes = this.attributes; - - // Handle both `"key", value` and `{key: value}` -style arguments. - if (key == null || typeof key === 'object') { - attrs = key; - options = val; - } else { - (attrs = {})[key] = val; - } - - options = _.extend({validate: true}, options); - - // If we're not waiting and attributes exist, save acts as - // `set(attr).save(null, opts)` with validation. Otherwise, check if - // the model will be valid when the attributes, if any, are set. - if (attrs && !options.wait) { - if (!this.set(attrs, options)) return false; - } else { - if (!this._validate(attrs, options)) return false; - } - - // Set temporary attributes if `{wait: true}`. - if (attrs && options.wait) { - this.attributes = _.extend({}, attributes, attrs); - } - - // After a successful server-side save, the client is (optionally) - // updated with the server-side state. - if (options.parse === void 0) options.parse = true; - var model = this; - var success = options.success; - options.success = function(resp) { - // Ensure attributes are restored during synchronous saves. - model.attributes = attributes; - var serverAttrs = model.parse(resp, options); - if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs); - if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) { - return false; - } - if (success) success(model, resp, options); - model.trigger('sync', model, resp, options); - }; - wrapError(this, options); - - method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update'); - if (method === 'patch') options.attrs = attrs; - xhr = this.sync(method, this, options); - - // Restore attributes. - if (attrs && options.wait) this.attributes = attributes; - - return xhr; - }, - - // Destroy this model on the server if it was already persisted. - // Optimistically removes the model from its collection, if it has one. - // If `wait: true` is passed, waits for the server to respond before removal. - destroy: function(options) { - options = options ? _.clone(options) : {}; - var model = this; - var success = options.success; - - var destroy = function() { - model.trigger('destroy', model, model.collection, options); - }; - - options.success = function(resp) { - if (options.wait || model.isNew()) destroy(); - if (success) success(model, resp, options); - if (!model.isNew()) model.trigger('sync', model, resp, options); - }; - - if (this.isNew()) { - options.success(); - return false; - } - wrapError(this, options); - - var xhr = this.sync('delete', this, options); - if (!options.wait) destroy(); - return xhr; - }, - - // Default URL for the model's representation on the server -- if you're - // using Backbone's restful methods, override this to change the endpoint - // that will be called. - url: function() { - var base = - _.result(this, 'urlRoot') || - _.result(this.collection, 'url') || - urlError(); - if (this.isNew()) return base; - return base.replace(/([^\/])$/, '$1/') + encodeURIComponent(this.id); - }, - - // **parse** converts a response into the hash of attributes to be `set` on - // the model. The default implementation is just to pass the response along. - parse: function(resp, options) { - return resp; - }, - - // Create a new model with identical attributes to this one. - clone: function() { - return new this.constructor(this.attributes); - }, - - // A model is new if it has never been saved to the server, and lacks an id. - isNew: function() { - return !this.has(this.idAttribute); - }, - - // Check if the model is currently in a valid state. - isValid: function(options) { - return this._validate({}, _.extend(options || {}, { validate: true })); - }, - - // Run validation against the next complete set of model attributes, - // returning `true` if all is well. Otherwise, fire an `"invalid"` event. - _validate: function(attrs, options) { - if (!options.validate || !this.validate) return true; - attrs = _.extend({}, this.attributes, attrs); - var error = this.validationError = this.validate(attrs, options) || null; - if (!error) return true; - this.trigger('invalid', this, error, _.extend(options, {validationError: error})); - return false; - } - - }); - - // Underscore methods that we want to implement on the Model. - var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit']; - - // Mix in each Underscore method as a proxy to `Model#attributes`. - _.each(modelMethods, function(method) { - Model.prototype[method] = function() { - var args = slice.call(arguments); - args.unshift(this.attributes); - return _[method].apply(_, args); - }; - }); - - // Backbone.Collection - // ------------------- - - // If models tend to represent a single row of data, a Backbone Collection is - // more analagous to a table full of data ... or a small slice or page of that - // table, or a collection of rows that belong together for a particular reason - // -- all of the messages in this particular folder, all of the documents - // belonging to this particular author, and so on. Collections maintain - // indexes of their models, both in order, and for lookup by `id`. - - // Create a new **Collection**, perhaps to contain a specific type of `model`. - // If a `comparator` is specified, the Collection will maintain - // its models in sort order, as they're added and removed. - var Collection = Backbone.Collection = function(models, options) { - options || (options = {}); - if (options.model) this.model = options.model; - if (options.comparator !== void 0) this.comparator = options.comparator; - this._reset(); - this.initialize.apply(this, arguments); - if (models) this.reset(models, _.extend({silent: true}, options)); - }; - - // Default options for `Collection#set`. - var setOptions = {add: true, remove: true, merge: true}; - var addOptions = {add: true, remove: false}; - - // Define the Collection's inheritable methods. - _.extend(Collection.prototype, Events, { - - // The default model for a collection is just a **Backbone.Model**. - // This should be overridden in most cases. - model: Model, - - // Initialize is an empty function by default. Override it with your own - // initialization logic. - initialize: function(){}, - - // The JSON representation of a Collection is an array of the - // models' attributes. - toJSON: function(options) { - return this.map(function(model){ return model.toJSON(options); }); - }, - - // Proxy `Backbone.sync` by default. - sync: function() { - return Backbone.sync.apply(this, arguments); - }, - - // Add a model, or list of models to the set. - add: function(models, options) { - return this.set(models, _.extend({merge: false}, options, addOptions)); - }, - - // Remove a model, or a list of models from the set. - remove: function(models, options) { - var singular = !_.isArray(models); - models = singular ? [models] : _.clone(models); - options || (options = {}); - var i, l, index, model; - for (i = 0, l = models.length; i < l; i++) { - model = models[i] = this.get(models[i]); - if (!model) continue; - delete this._byId[model.id]; - delete this._byId[model.cid]; - index = this.indexOf(model); - this.models.splice(index, 1); - this.length--; - if (!options.silent) { - options.index = index; - model.trigger('remove', model, this, options); - } - this._removeReference(model, options); - } - return singular ? models[0] : models; - }, - - // Update a collection by `set`-ing a new list of models, adding new ones, - // removing models that are no longer present, and merging models that - // already exist in the collection, as necessary. Similar to **Model#set**, - // the core operation for updating the data contained by the collection. - set: function(models, options) { - options = _.defaults({}, options, setOptions); - if (options.parse) models = this.parse(models, options); - var singular = !_.isArray(models); - models = singular ? (models ? [models] : []) : _.clone(models); - var i, l, id, model, attrs, existing, sort; - var at = options.at; - var targetModel = this.model; - var sortable = this.comparator && (at == null) && options.sort !== false; - var sortAttr = _.isString(this.comparator) ? this.comparator : null; - var toAdd = [], toRemove = [], modelMap = {}; - var add = options.add, merge = options.merge, remove = options.remove; - var order = !sortable && add && remove ? [] : false; - - // Turn bare objects into model references, and prevent invalid models - // from being added. - for (i = 0, l = models.length; i < l; i++) { - attrs = models[i] || {}; - if (attrs instanceof Model) { - id = model = attrs; - } else { - id = attrs[targetModel.prototype.idAttribute || 'id']; - } - - // If a duplicate is found, prevent it from being added and - // optionally merge it into the existing model. - if (existing = this.get(id)) { - if (remove) modelMap[existing.cid] = true; - if (merge) { - attrs = attrs === model ? model.attributes : attrs; - if (options.parse) attrs = existing.parse(attrs, options); - existing.set(attrs, options); - if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true; - } - models[i] = existing; - - // If this is a new, valid model, push it to the `toAdd` list. - } else if (add) { - model = models[i] = this._prepareModel(attrs, options); - if (!model) continue; - toAdd.push(model); - this._addReference(model, options); - } - - // Do not add multiple models with the same `id`. - model = existing || model; - if (order && (model.isNew() || !modelMap[model.id])) order.push(model); - modelMap[model.id] = true; - } - - // Remove nonexistent models if appropriate. - if (remove) { - for (i = 0, l = this.length; i < l; ++i) { - if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model); - } - if (toRemove.length) this.remove(toRemove, options); - } - - // See if sorting is needed, update `length` and splice in new models. - if (toAdd.length || (order && order.length)) { - if (sortable) sort = true; - this.length += toAdd.length; - if (at != null) { - for (i = 0, l = toAdd.length; i < l; i++) { - this.models.splice(at + i, 0, toAdd[i]); - } - } else { - if (order) this.models.length = 0; - var orderedModels = order || toAdd; - for (i = 0, l = orderedModels.length; i < l; i++) { - this.models.push(orderedModels[i]); - } - } - } - - // Silently sort the collection if appropriate. - if (sort) this.sort({silent: true}); - - // Unless silenced, it's time to fire all appropriate add/sort events. - if (!options.silent) { - for (i = 0, l = toAdd.length; i < l; i++) { - (model = toAdd[i]).trigger('add', model, this, options); - } - if (sort || (order && order.length)) this.trigger('sort', this, options); - } - - // Return the added (or merged) model (or models). - return singular ? models[0] : models; - }, - - // When you have more items than you want to add or remove individually, - // you can reset the entire set with a new list of models, without firing - // any granular `add` or `remove` events. Fires `reset` when finished. - // Useful for bulk operations and optimizations. - reset: function(models, options) { - options || (options = {}); - for (var i = 0, l = this.models.length; i < l; i++) { - this._removeReference(this.models[i], options); - } - options.previousModels = this.models; - this._reset(); - models = this.add(models, _.extend({silent: true}, options)); - if (!options.silent) this.trigger('reset', this, options); - return models; - }, - - // Add a model to the end of the collection. - push: function(model, options) { - return this.add(model, _.extend({at: this.length}, options)); - }, - - // Remove a model from the end of the collection. - pop: function(options) { - var model = this.at(this.length - 1); - this.remove(model, options); - return model; - }, - - // Add a model to the beginning of the collection. - unshift: function(model, options) { - return this.add(model, _.extend({at: 0}, options)); - }, - - // Remove a model from the beginning of the collection. - shift: function(options) { - var model = this.at(0); - this.remove(model, options); - return model; - }, - - // Slice out a sub-array of models from the collection. - slice: function() { - return slice.apply(this.models, arguments); - }, - - // Get a model from the set by id. - get: function(obj) { - if (obj == null) return void 0; - return this._byId[obj] || this._byId[obj.id] || this._byId[obj.cid]; - }, - - // Get the model at the given index. - at: function(index) { - return this.models[index]; - }, - - // Return models with matching attributes. Useful for simple cases of - // `filter`. - where: function(attrs, first) { - if (_.isEmpty(attrs)) return first ? void 0 : []; - return this[first ? 'find' : 'filter'](function(model) { - for (var key in attrs) { - if (attrs[key] !== model.get(key)) return false; - } - return true; - }); - }, - - // Return the first model with matching attributes. Useful for simple cases - // of `find`. - findWhere: function(attrs) { - return this.where(attrs, true); - }, - - // Force the collection to re-sort itself. You don't need to call this under - // normal circumstances, as the set will maintain sort order as each item - // is added. - sort: function(options) { - if (!this.comparator) throw new Error('Cannot sort a set without a comparator'); - options || (options = {}); - - // Run sort based on type of `comparator`. - if (_.isString(this.comparator) || this.comparator.length === 1) { - this.models = this.sortBy(this.comparator, this); - } else { - this.models.sort(_.bind(this.comparator, this)); - } - - if (!options.silent) this.trigger('sort', this, options); - return this; - }, - - // Pluck an attribute from each model in the collection. - pluck: function(attr) { - return _.invoke(this.models, 'get', attr); - }, - - // Fetch the default set of models for this collection, resetting the - // collection when they arrive. If `reset: true` is passed, the response - // data will be passed through the `reset` method instead of `set`. - fetch: function(options) { - options = options ? _.clone(options) : {}; - if (options.parse === void 0) options.parse = true; - var success = options.success; - var collection = this; - options.success = function(resp) { - var method = options.reset ? 'reset' : 'set'; - collection[method](resp, options); - if (success) success(collection, resp, options); - collection.trigger('sync', collection, resp, options); - }; - wrapError(this, options); - return this.sync('read', this, options); - }, - - // Create a new instance of a model in this collection. Add the model to the - // collection immediately, unless `wait: true` is passed, in which case we - // wait for the server to agree. - create: function(model, options) { - options = options ? _.clone(options) : {}; - if (!(model = this._prepareModel(model, options))) return false; - if (!options.wait) this.add(model, options); - var collection = this; - var success = options.success; - options.success = function(model, resp) { - if (options.wait) collection.add(model, options); - if (success) success(model, resp, options); - }; - model.save(null, options); - return model; - }, - - // **parse** converts a response into a list of models to be added to the - // collection. The default implementation is just to pass it through. - parse: function(resp, options) { - return resp; - }, - - // Create a new collection with an identical list of models as this one. - clone: function() { - return new this.constructor(this.models); - }, - - // Private method to reset all internal state. Called when the collection - // is first initialized or reset. - _reset: function() { - this.length = 0; - this.models = []; - this._byId = {}; - }, - - // Prepare a hash of attributes (or other model) to be added to this - // collection. - _prepareModel: function(attrs, options) { - if (attrs instanceof Model) return attrs; - options = options ? _.clone(options) : {}; - options.collection = this; - var model = new this.model(attrs, options); - if (!model.validationError) return model; - this.trigger('invalid', this, model.validationError, options); - return false; - }, - - // Internal method to create a model's ties to a collection. - _addReference: function(model, options) { - this._byId[model.cid] = model; - if (model.id != null) this._byId[model.id] = model; - if (!model.collection) model.collection = this; - model.on('all', this._onModelEvent, this); - }, - - // Internal method to sever a model's ties to a collection. - _removeReference: function(model, options) { - if (this === model.collection) delete model.collection; - model.off('all', this._onModelEvent, this); - }, - - // Internal method called every time a model in the set fires an event. - // Sets need to update their indexes when models change ids. All other - // events simply proxy through. "add" and "remove" events that originate - // in other collections are ignored. - _onModelEvent: function(event, model, collection, options) { - if ((event === 'add' || event === 'remove') && collection !== this) return; - if (event === 'destroy') this.remove(model, options); - if (model && event === 'change:' + model.idAttribute) { - delete this._byId[model.previous(model.idAttribute)]; - if (model.id != null) this._byId[model.id] = model; - } - this.trigger.apply(this, arguments); - } - - }); - - // Underscore methods that we want to implement on the Collection. - // 90% of the core usefulness of Backbone Collections is actually implemented - // right here: - var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl', - 'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select', - 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke', - 'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest', - 'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle', - 'lastIndexOf', 'isEmpty', 'chain', 'sample']; - - // Mix in each Underscore method as a proxy to `Collection#models`. - _.each(methods, function(method) { - Collection.prototype[method] = function() { - var args = slice.call(arguments); - args.unshift(this.models); - return _[method].apply(_, args); - }; - }); - - // Underscore methods that take a property name as an argument. - var attributeMethods = ['groupBy', 'countBy', 'sortBy', 'indexBy']; - - // Use attributes instead of properties. - _.each(attributeMethods, function(method) { - Collection.prototype[method] = function(value, context) { - var iterator = _.isFunction(value) ? value : function(model) { - return model.get(value); - }; - return _[method](this.models, iterator, context); - }; - }); - - // Backbone.View - // ------------- - - // Backbone Views are almost more convention than they are actual code. A View - // is simply a JavaScript object that represents a logical chunk of UI in the - // DOM. This might be a single item, an entire list, a sidebar or panel, or - // even the surrounding frame which wraps your whole app. Defining a chunk of - // UI as a **View** allows you to define your DOM events declaratively, without - // having to worry about render order ... and makes it easy for the view to - // react to specific changes in the state of your models. - - // Creating a Backbone.View creates its initial element outside of the DOM, - // if an existing element is not provided... - var View = Backbone.View = function(options) { - this.cid = _.uniqueId('view'); - options || (options = {}); - _.extend(this, _.pick(options, viewOptions)); - this._ensureElement(); - this.initialize.apply(this, arguments); - this.delegateEvents(); - }; - - // Cached regex to split keys for `delegate`. - var delegateEventSplitter = /^(\S+)\s*(.*)$/; - - // List of view options to be merged as properties. - var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events']; - - // Set up all inheritable **Backbone.View** properties and methods. - _.extend(View.prototype, Events, { - - // The default `tagName` of a View's element is `"div"`. - tagName: 'div', - - // jQuery delegate for element lookup, scoped to DOM elements within the - // current view. This should be preferred to global lookups where possible. - $: function(selector) { - return this.$el.find(selector); - }, - - // Initialize is an empty function by default. Override it with your own - // initialization logic. - initialize: function(){}, - - // **render** is the core function that your view should override, in order - // to populate its element (`this.el`), with the appropriate HTML. The - // convention is for **render** to always return `this`. - render: function() { - return this; - }, - - // Remove this view by taking the element out of the DOM, and removing any - // applicable Backbone.Events listeners. - remove: function() { - this.$el.remove(); - this.stopListening(); - return this; - }, - - // Change the view's element (`this.el` property), including event - // re-delegation. - setElement: function(element, delegate) { - if (this.$el) this.undelegateEvents(); - this.$el = element instanceof Backbone.$ ? element : Backbone.$(element); - this.el = this.$el[0]; - if (delegate !== false) this.delegateEvents(); - return this; - }, - - // Set callbacks, where `this.events` is a hash of - // - // *{"event selector": "callback"}* - // - // { - // 'mousedown .title': 'edit', - // 'click .button': 'save', - // 'click .open': function(e) { ... } - // } - // - // pairs. Callbacks will be bound to the view, with `this` set properly. - // Uses event delegation for efficiency. - // Omitting the selector binds the event to `this.el`. - // This only works for delegate-able events: not `focus`, `blur`, and - // not `change`, `submit`, and `reset` in Internet Explorer. - delegateEvents: function(events) { - if (!(events || (events = _.result(this, 'events')))) return this; - this.undelegateEvents(); - for (var key in events) { - var method = events[key]; - if (!_.isFunction(method)) method = this[events[key]]; - if (!method) continue; - - var match = key.match(delegateEventSplitter); - var eventName = match[1], selector = match[2]; - method = _.bind(method, this); - eventName += '.delegateEvents' + this.cid; - if (selector === '') { - this.$el.on(eventName, method); - } else { - this.$el.on(eventName, selector, method); - } - } - return this; - }, - - // Clears all callbacks previously bound to the view with `delegateEvents`. - // You usually don't need to use this, but may wish to if you have multiple - // Backbone views attached to the same DOM element. - undelegateEvents: function() { - this.$el.off('.delegateEvents' + this.cid); - return this; - }, - - // Ensure that the View has a DOM element to render into. - // If `this.el` is a string, pass it through `$()`, take the first - // matching element, and re-assign it to `el`. Otherwise, create - // an element from the `id`, `className` and `tagName` properties. - _ensureElement: function() { - if (!this.el) { - var attrs = _.extend({}, _.result(this, 'attributes')); - if (this.id) attrs.id = _.result(this, 'id'); - if (this.className) attrs['class'] = _.result(this, 'className'); - var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs); - this.setElement($el, false); - } else { - this.setElement(_.result(this, 'el'), false); - } - } - - }); - - // Backbone.sync - // ------------- - - // Override this function to change the manner in which Backbone persists - // models to the server. You will be passed the type of request, and the - // model in question. By default, makes a RESTful Ajax request - // to the model's `url()`. Some possible customizations could be: - // - // * Use `setTimeout` to batch rapid-fire updates into a single request. - // * Send up the models as XML instead of JSON. - // * Persist models via WebSockets instead of Ajax. - // - // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests - // as `POST`, with a `_method` parameter containing the true HTTP method, - // as well as all requests with the body as `application/x-www-form-urlencoded` - // instead of `application/json` with the model in a param named `model`. - // Useful when interfacing with server-side languages like **PHP** that make - // it difficult to read the body of `PUT` requests. - Backbone.sync = function(method, model, options) { - var type = methodMap[method]; - - // Default options, unless specified. - _.defaults(options || (options = {}), { - emulateHTTP: Backbone.emulateHTTP, - emulateJSON: Backbone.emulateJSON - }); - - // Default JSON-request options. - var params = {type: type, dataType: 'json'}; - - // Ensure that we have a URL. - if (!options.url) { - params.url = _.result(model, 'url') || urlError(); - } - - // Ensure that we have the appropriate request data. - if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) { - params.contentType = 'application/json'; - params.data = JSON.stringify(options.attrs || model.toJSON(options)); - } - - // For older servers, emulate JSON by encoding the request into an HTML-form. - if (options.emulateJSON) { - params.contentType = 'application/x-www-form-urlencoded'; - params.data = params.data ? {model: params.data} : {}; - } - - // For older servers, emulate HTTP by mimicking the HTTP method with `_method` - // And an `X-HTTP-Method-Override` header. - if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) { - params.type = 'POST'; - if (options.emulateJSON) params.data._method = type; - var beforeSend = options.beforeSend; - options.beforeSend = function(xhr) { - xhr.setRequestHeader('X-HTTP-Method-Override', type); - if (beforeSend) return beforeSend.apply(this, arguments); - }; - } - - // Don't process data on a non-GET request. - if (params.type !== 'GET' && !options.emulateJSON) { - params.processData = false; - } - - // If we're sending a `PATCH` request, and we're in an old Internet Explorer - // that still has ActiveX enabled by default, override jQuery to use that - // for XHR instead. Remove this line when jQuery supports `PATCH` on IE8. - if (params.type === 'PATCH' && noXhrPatch) { - params.xhr = function() { - return new ActiveXObject("Microsoft.XMLHTTP"); - }; - } - - // Make the request, allowing the user to override any Ajax options. - var xhr = options.xhr = Backbone.ajax(_.extend(params, options)); - model.trigger('request', model, xhr, options); - return xhr; - }; - - var noXhrPatch = - typeof window !== 'undefined' && !!window.ActiveXObject && - !(window.XMLHttpRequest && (new XMLHttpRequest).dispatchEvent); - - // Map from CRUD to HTTP for our default `Backbone.sync` implementation. - var methodMap = { - 'create': 'POST', - 'update': 'PUT', - 'patch': 'PATCH', - 'delete': 'DELETE', - 'read': 'GET' - }; - - // Set the default implementation of `Backbone.ajax` to proxy through to `$`. - // Override this if you'd like to use a different library. - Backbone.ajax = function() { - return Backbone.$.ajax.apply(Backbone.$, arguments); - }; - - // Backbone.Router - // --------------- - - // Routers map faux-URLs to actions, and fire events when routes are - // matched. Creating a new one sets its `routes` hash, if not set statically. - var Router = Backbone.Router = function(options) { - options || (options = {}); - if (options.routes) this.routes = options.routes; - this._bindRoutes(); - this.initialize.apply(this, arguments); - }; - - // Cached regular expressions for matching named param parts and splatted - // parts of route strings. - var optionalParam = /\((.*?)\)/g; - var namedParam = /(\(\?)?:\w+/g; - var splatParam = /\*\w+/g; - var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g; - - // Set up all inheritable **Backbone.Router** properties and methods. - _.extend(Router.prototype, Events, { - - // Initialize is an empty function by default. Override it with your own - // initialization logic. - initialize: function(){}, - - // Manually bind a single named route to a callback. For example: - // - // this.route('search/:query/p:num', 'search', function(query, num) { - // ... - // }); - // - route: function(route, name, callback) { - if (!_.isRegExp(route)) route = this._routeToRegExp(route); - if (_.isFunction(name)) { - callback = name; - name = ''; - } - if (!callback) callback = this[name]; - var router = this; - Backbone.history.route(route, function(fragment) { - var args = router._extractParameters(route, fragment); - router.execute(callback, args); - router.trigger.apply(router, ['route:' + name].concat(args)); - router.trigger('route', name, args); - Backbone.history.trigger('route', router, name, args); - }); - return this; - }, - - // Execute a route handler with the provided parameters. This is an - // excellent place to do pre-route setup or post-route cleanup. - execute: function(callback, args) { - if (callback) callback.apply(this, args); - }, - - // Simple proxy to `Backbone.history` to save a fragment into the history. - navigate: function(fragment, options) { - Backbone.history.navigate(fragment, options); - return this; - }, - - // Bind all defined routes to `Backbone.history`. We have to reverse the - // order of the routes here to support behavior where the most general - // routes can be defined at the bottom of the route map. - _bindRoutes: function() { - if (!this.routes) return; - this.routes = _.result(this, 'routes'); - var route, routes = _.keys(this.routes); - while ((route = routes.pop()) != null) { - this.route(route, this.routes[route]); - } - }, - - // Convert a route string into a regular expression, suitable for matching - // against the current location hash. - _routeToRegExp: function(route) { - route = route.replace(escapeRegExp, '\\$&') - .replace(optionalParam, '(?:$1)?') - .replace(namedParam, function(match, optional) { - return optional ? match : '([^/?]+)'; - }) - .replace(splatParam, '([^?]*?)'); - return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$'); - }, - - // Given a route, and a URL fragment that it matches, return the array of - // extracted decoded parameters. Empty or unmatched parameters will be - // treated as `null` to normalize cross-browser behavior. - _extractParameters: function(route, fragment) { - var params = route.exec(fragment).slice(1); - return _.map(params, function(param, i) { - // Don't decode the search params. - if (i === params.length - 1) return param || null; - return param ? decodeURIComponent(param) : null; - }); - } - - }); - - // Backbone.History - // ---------------- - - // Handles cross-browser history management, based on either - // [pushState](http://diveintohtml5.info/history.html) and real URLs, or - // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange) - // and URL fragments. If the browser supports neither (old IE, natch), - // falls back to polling. - var History = Backbone.History = function() { - this.handlers = []; - _.bindAll(this, 'checkUrl'); - - // Ensure that `History` can be used outside of the browser. - if (typeof window !== 'undefined') { - this.location = window.location; - this.history = window.history; - } - }; - - // Cached regex for stripping a leading hash/slash and trailing space. - var routeStripper = /^[#\/]|\s+$/g; - - // Cached regex for stripping leading and trailing slashes. - var rootStripper = /^\/+|\/+$/g; - - // Cached regex for detecting MSIE. - var isExplorer = /msie [\w.]+/; - - // Cached regex for removing a trailing slash. - var trailingSlash = /\/$/; - - // Cached regex for stripping urls of hash. - var pathStripper = /#.*$/; - - // Has the history handling already been started? - History.started = false; - - // Set up all inheritable **Backbone.History** properties and methods. - _.extend(History.prototype, Events, { - - // The default interval to poll for hash changes, if necessary, is - // twenty times a second. - interval: 50, - - // Are we at the app root? - atRoot: function() { - return this.location.pathname.replace(/[^\/]$/, '$&/') === this.root; - }, - - // Gets the true hash value. Cannot use location.hash directly due to bug - // in Firefox where location.hash will always be decoded. - getHash: function(window) { - var match = (window || this).location.href.match(/#(.*)$/); - return match ? match[1] : ''; - }, - - // Get the cross-browser normalized URL fragment, either from the URL, - // the hash, or the override. - getFragment: function(fragment, forcePushState) { - if (fragment == null) { - if (this._hasPushState || !this._wantsHashChange || forcePushState) { - fragment = decodeURI(this.location.pathname + this.location.search); - var root = this.root.replace(trailingSlash, ''); - if (!fragment.indexOf(root)) fragment = fragment.slice(root.length); - } else { - fragment = this.getHash(); - } - } - return fragment.replace(routeStripper, ''); - }, - - // Start the hash change handling, returning `true` if the current URL matches - // an existing route, and `false` otherwise. - start: function(options) { - if (History.started) throw new Error("Backbone.history has already been started"); - History.started = true; - - // Figure out the initial configuration. Do we need an iframe? - // Is pushState desired ... is it available? - this.options = _.extend({root: '/'}, this.options, options); - this.root = this.options.root; - this._wantsHashChange = this.options.hashChange !== false; - this._wantsPushState = !!this.options.pushState; - this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState); - var fragment = this.getFragment(); - var docMode = document.documentMode; - var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7)); - - // Normalize root to always include a leading and trailing slash. - this.root = ('/' + this.root + '/').replace(rootStripper, '/'); - - if (oldIE && this._wantsHashChange) { - var frame = Backbone.$('