<commit_before>import React, {
  View,
  Text,
  StyleSheet,
  NavigatorIOS,
  TabBarIOS,
  ToolbarAndroid,
  Platform
} from 'react-native'

import Icon from 'react-native-vector-icons/Ionicons'

import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import * as actions from '../store/actions'

import OriginalView from './Original'
import CommunityView from './Community'
import DribbbleView from './Dribbble'
import CNodeView from './CNode'

const navbars = [
  {
    title: '原生组件',
    icon: 'pizza',
    name: 'original',
    view: OriginalView
  },
  {
    title: '社区组件',
    icon: 'coffee',
    name: 'community',
    view: CommunityView
  },
  {
    title: 'Dribble',
    icon: 'social-dribbble-outline',
    name: 'dribbble',
    view: DribbbleView
  },
  {
    title: 'CNode',
    icon: 'social-nodejs',
    name: 'cnodejs',
    view: CNodeView
  }
]

class App extends React.Component {
  constructor (props) {
    super(props)

    this.state = {
      selectedTab: "original"
    }
  }

  _renderTabBarItem (title, icon, name, view) {
    return (
      <Icon.TabBarItem
        title={title}
        iconName={icon}
        selectedIconName={icon}
        selected={this.state.selectedTab === name}
        onPress={() => {
          this.setState({
            selectedTab: name
          })
        }}>
        <NavigatorIOS style={styles.wrapper}
          initialRoute={{
            component: view,
            title: title
          }}
        />
      </Icon.TabBarItem>
    )
  }

  render () {
    if (Platform.OS === 'android') {
      return (
        <ToolbarAndroid
          actions={[{title: 'fake', show: 'always'}]}
          navIcon={require('image!ic_menu_black_24dp')}
          style={styles.toolbar}
          title="Toolbar"
        />
      )
    } else {
      return (
        <TabBarIOS tintColor={"#ea4c89"}>
          {navbars.map(item => {
            return this._renderTabBarItem(item.title, item.icon, item.name, item.view)
          })}
        </TabBarIOS>
      )
    }
  }
}

const styles = StyleSheet.create({
  tabContent: {
    flex: 1,
    alignItems: "center"
  },
  tabText: {
    color: "white",
    margin: 50
  },
  wrapper: {
    flex: 1
  },
  toolbar: {
    backgroundColor: '#e9eaed',
    height: 56,
  }
})

const stateToProps = (state) => ({...state})
const dispatchToProps = (dispatch) => bindActionCreators({...actions}, dispatch)

export default connect(stateToProps, dispatchToProps)(App)
<commit_msg>添加DrawerLayoutAndroid<commit_after>import React, {
  View,
  Text,
  StyleSheet,
  NavigatorIOS,
  TabBarIOS,
  ToolbarAndroid,
  DrawerLayoutAndroid,
  Platform
} from 'react-native'

import Icon from 'react-native-vector-icons/Ionicons'

import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import * as actions from '../store/actions'

import OriginalView from './Original'
import CommunityView from './Community'
import DribbbleView from './Dribbble'
import CNodeView from './CNode'

const navbars = [
  {
    title: '原生组件',
    icon: 'pizza',
    name: 'original',
    view: OriginalView
  },
  {
    title: '社区组件',
    icon: 'coffee',
    name: 'community',
    view: CommunityView
  },
  {
    title: 'Dribble',
    icon: 'social-dribbble-outline',
    name: 'dribbble',
    view: DribbbleView
  },
  {
    title: 'CNode',
    icon: 'social-nodejs',
    name: 'cnodejs',
    view: CNodeView
  }
]

class App extends React.Component {
  constructor (props) {
    super(props)

    this.state = {
      selectedTab: "original"
    }
  }

  _renderTabBarItem (title, icon, name, view) {
    return (
      <Icon.TabBarItem
        title={title}
        iconName={icon}
        selectedIconName={icon}
        selected={this.state.selectedTab === name}
        onPress={() => {
          this.setState({
            selectedTab: name
          })
        }}>
        <NavigatorIOS style={styles.wrapper}
          initialRoute={{
            component: view,
            title: title
          }}
        />
      </Icon.TabBarItem>
    )
  }

  _openDrawer () {
    console.log('true')
    this.refs['DRAWER'].openDrawer()
  }

  render () {
    const navigationView = (
      <View style={{flex: 1, backgroundColor: '#fff'}}>
        <Text style={{margin: 10, fontSize: 15, textAlign: 'left'}}>I'm in the Drawer!</Text>
      </View>
    )

    if (Platform.OS === 'android') {
      return (
          <DrawerLayoutAndroid
            ref={'DRAWER'}
            drawerWidth={300}
            drawerPosition={DrawerLayoutAndroid.positions.Left}
            keyboardDismissMode="on-drag"
            renderNavigationView={() => navigationView}>
            <View style={{flex: 1, flexDirection: 'column', backgroundColor: '#FAFAFA'}}>
              <ToolbarAndroid
                actions={[{title: 'fakes', show: 'always'}]}
                navIcon={require('image!ic_menu_black_24dp')}
                onIconClicked={this._openDrawer.bind(this)}
                style={styles.toolbar}
                title="Toolbar"
              />
            </View>
          </DrawerLayoutAndroid>
      )
    } else {
      return (
        <TabBarIOS tintColor={"#ea4c89"}>
          {navbars.map(item => {
            return this._renderTabBarItem(item.title, item.icon, item.name, item.view)
          })}
        </TabBarIOS>
      )
    }
  }
}

const styles = StyleSheet.create({
  tabContent: {
    flex: 1,
    alignItems: "center"
  },
  tabText: {
    color: "white",
    margin: 50
  },
  wrapper: {
    flex: 1
  },
  toolbar: {
    backgroundColor: '#e9eaed',
    height: 56,
  }
})

const stateToProps = (state) => ({...state})
const dispatchToProps = (dispatch) => bindActionCreators({...actions}, dispatch)

export default connect(stateToProps, dispatchToProps)(App)
<|endoftext|>


<commit_before>require('./vr-register-element');

var VRObject = require('./core/vr-object');
var VRNode = require('./core/vr-node');
var THREE = require('../lib/three');
var VRUtils = require('./vr-utils');

require('./core/vr-camera');
require('./core/vr-scene');
require('./core/vr-assets');

require('./vr-animation');
require('./vr-behavior');
require('./vr-controls');
require('./vr-cursor');
require('./vr-fog');
require('./vr-geometry');
require('./vr-material');
require('./vr-mesh');

module.exports = {
  THREE: THREE,
  VRObject: VRObject,
  VRNode: VRNode,
  utils: VRUtils
};<commit_msg>publish components<commit_after>require('./vr-register-element');

var VRObject = require('./core/vr-object');
var VRNode = require('./core/vr-node');
var THREE = require('../lib/three');
var VRUtils = require('./vr-utils');

require('./core/vr-camera');
require('./core/vr-scene');
require('./core/vr-assets');

require('./vr-animation');
require('./vr-behavior');
require('./vr-controls');
require('./vr-cursor');
require('./vr-fog');
require('./vr-geometry');
require('./vr-material');
require('./vr-mesh');

// Load some default components.
require('../components/vr-audio');
require('../components/vr-cube');
require('../components/vr-curvedPlane1');
require('../components/vr-curvedPlane2');
require('../components/vr-grid');
require('../components/vr-hemispherelight');
require('../components/vr-image');
require('../components/vr-model');
require('../components/vr-obj-loader');
require('../components/vr-plane');
require('../components/vr-skybox');
require('../components/vr-sphere');
require('../components/vr-video');
require('../components/vr-video360');

module.exports = {
  THREE: THREE,
  VRObject: VRObject,
  VRNode: VRNode,
  utils: VRUtils
};<|endoftext|>


<commit_before>Object.assign(pc, function () {
    'use strict';

    /**
     * @private
     * @constructor
     * @name pc.BundleRegistry
     * @param {pc.AssetRegistry} assets The asset registry
     * @classdesc Keeps track of which assets are in bundles and loads files from bundles.
     */
    var BundleRegistry = function (assets) {
        this._assets = assets;

        // index of bundle assets
        this._bundleAssets = {};
        // index asset id to one more bundle assets
        this._assetsInBundles = {};
        // index file urls to one or more bundle assets
        this._urlsInBundles = {};
        // contains requests to load file URLs indexed by URL
        this._fileRequests = {};

        this._assets.on('add', this._onAssetAdded, this);
        this._assets.on('remove', this._onAssetRemoved, this);
    };

    Object.assign(BundleRegistry.prototype, {
        // Add asset in internal indexes
        _onAssetAdded: function (asset) {
            // if this is a bundle asset then add it and
            // index its referenced assets
            if (asset.type === 'bundle') {
                this._bundleAssets[asset.id] = asset;

                this._registerBundleEventListeners(asset.id);

                for (var i = 0, len = asset.data.assets.length; i < len; i++) {
                    this._indexAssetInBundle(asset.data.assets[i], asset);
                }
            } else {
                // if this is not a bundle then index its URLs
                if (this._assetsInBundles[asset.id]) {
                    this._indexAssetFileUrls(asset);
                }
            }
        },

        _registerBundleEventListeners: function (bundleAssetId) {
            this._assets.on('load:' + bundleAssetId, this._onBundleLoaded, this);
            this._assets.on('error:' + bundleAssetId, this._onBundleError, this);
        },

        _unregisterBundleEventListeners: function (bundleAssetId) {
            this._assets.off('load:' + bundleAssetId, this._onBundleLoaded, this);
            this._assets.off('error:' + bundleAssetId, this._onBundleError, this);
        },

        // Index the specified asset id and its file URLs so that
        // the registry knows that the asset is in that bundle
        _indexAssetInBundle: function (assetId, bundleAsset) {
            if (! this._assetsInBundles[assetId]) {
                this._assetsInBundles[assetId] = [bundleAsset];
            } else {
                var bundles = this._assetsInBundles[assetId];
                var idx = bundles.indexOf(bundleAsset);
                if (idx === -1) {
                    bundles.push(bundleAsset);
                }
            }

            var asset = this._assets.get(assetId);
            if (asset) {
                this._indexAssetFileUrls(asset);
            }
        },

        // Index the file URLs of the specified asset
        _indexAssetFileUrls: function (asset) {
            var urls = this._getAssetFileUrls(asset);
            if (! urls) return;

            for (var i = 0, len = urls.length; i < len; i++) {
                var url = urls[i];
                // Just set the URL to point to the same bundles as the asset does.
                // This is a performance/memory optimization and it assumes that
                // the URL will not exist in any other asset. If that does happen then
                // this will not work as expected if the asset is removed, as the URL will
                // be removed too.
                this._urlsInBundles[url] = this._assetsInBundles[asset.id];
            }
        },

        // Get all the possible URLs of an asset
        _getAssetFileUrls: function (asset) {
            var url = asset.getFileUrl();
            if (! url) return null;

            url = this._normalizeUrl(url);
            var urls = [url];

            // a font might have additional files
            // so add them in the list
            if (asset.type === 'font') {
                var numFiles = asset.data.info.maps.length;
                for (var i = 1; i < numFiles; i++) {
                    urls.push(url.replace('.png', i + '.png'));
                }
            }

            return urls;
        },

        // Removes query parameters from a URL
        _normalizeUrl: function (url) {
            return url && url.split('?')[0];
        },

        // Remove asset from internal indexes
        _onAssetRemoved: function (asset) {
            if (asset.type === 'bundle') {
                // remove bundle from index
                delete this._bundleAssets[asset.id];

                // remove event listeners
                this._unregisterBundleEventListeners(asset.id);

                // remove bundle from _assetsInBundles and _urlInBundles indexes
                var idx, id;
                for (id in this._assetsInBundles) {
                    var array = this._assetsInBundles[id];
                    idx = array.indexOf(asset);
                    if (idx !== -1) {
                        array.splice(idx, 1);
                        if (! array.length) {
                            delete this._assetsInBundles[id];

                            // make sure we do not leave that array in
                            // any _urlInBundles entries
                            for (var url in this._urlsInBundles) {
                                if (this._urlsInBundles[url] === array) {
                                    delete this._urlsInBundles[url];
                                }
                            }
                        }
                    }
                }

                // fail any pending requests for this bundle
                this._onBundleError('Bundle ' + asset.id + ' was removed', asset);

            } else if (this._assetsInBundles[asset.id]) {
                // remove asset from _assetInBundles
                delete this._assetsInBundles[asset.id];

                // remove asset urls from _urlsInBundles
                var urls = this._getAssetFileUrls(asset);
                for (var i = 0, len = urls.length; i < len; i++) {
                    delete this._urlsInBundles[urls[i]];
                }
            }

        },

        // If we have any pending file requests
        // that can be satisfied by the specified bundle
        // then resolve them
        _onBundleLoaded: function (bundleAsset) {
            // this can happen if the bundleAsset failed
            // to create its resource
            if (! bundleAsset.resource) {
                this._onBundleError('Bundle ' + bundleAsset.id + ' failed to load', bundleAsset);
                return;
            }

            // on next tick resolve the pending asset requests
            // don't do it on the same tick because that ties the loading
            // of the bundle to the loading of all the assets
            requestAnimationFrame(function () {
                for (var url in this._fileRequests) {
                    var bundles = this._urlsInBundles[url];
                    if (!bundles || bundles.indexOf(bundleAsset) === -1) continue;

                    var requests = this._fileRequests[url];
                    for (var i = 0, len = requests.length; i < len; i++) {
                        requests[i](null, bundleAsset.resource.getBlobUrl(decodeURIComponent(url)));
                    }

                    delete this._fileRequests[url];
                }
            }.bind(this));
        },

        // If we have outstanding file requests for any
        // of the URLs in the specified bundle then search for
        // other bundles that can satisfy these requests.
        // If we do not find any other bundles then fail
        // those pending file requests with the specified error.
        _onBundleError: function (err, bundleAsset) {
            for (var url in this._fileRequests) {
                var bundle = this._findLoadedOrLoadingBundleForUrl(url);
                if (! bundle) {
                    var requests = this._fileRequests[url];
                    for (var i = 0, len = requests.length; i < len; i++) {
                        requests[i](err);
                    }

                    delete this._fileRequests[url];

                }
            }
        },

        // Finds a bundle that contains the specified URL but
        // only returns the bundle if it's either loaded or being loaded
        _findLoadedOrLoadingBundleForUrl: function (url) {
            var bundles = this._urlsInBundles[url];
            if (! bundles) return null;

            // look for loaded bundle first...
            var len = bundles.length;
            var i;
            for (i = 0; i < len; i++) {
                // 'loaded' can be true but if there was an error
                // then 'resource' would be null
                if (bundles[i].loaded && bundles[i].resource) {
                    return bundles[i];
                }
            }

            // ...then look for loading bundles
            for (i = 0; i < len; i++) {
                if (bundles[i].loading) {
                    return bundles[i];
                }
            }

            return null;
        },

        /**
         * @private
         * @function
         * @name pc.BundleRegistry#listBundlesForAsset
         * @description Lists all of the available bundles that reference the specified asset id.
         * @param {pc.Asset} asset The asset
         * @returns {pc.Asset[]} An array of bundle assets.
         */
        listBundlesForAsset: function (asset) {
            var bundles = this._assetsInBundles[asset.id];
            if (bundles) {
                return bundles.slice();
            }

            return [];
        },

        /**
         * @private
         * @function
         * @name pc.BundleRegistry#list
         * @description Lists all of the available bundles. This includes bundles that are not loaded.
         * @returns {pc.Asset[]} An array of bundle assets.
         */
        list: function () {
            var result = [];
            for (var id in this._bundleAssets) {
                result.push(this._bundleAssets[id]);
            }

            return result;
        },

        /**
         * @private
         * @function
         * @name pc.BundleRegistry#hasUrl
         * @description Returns true if there is a bundle that contains the specified URL
         * @param {String} url The url
         * @returns {Boolean} True or false
         */
        hasUrl: function (url) {
            return !!this._urlsInBundles[url];
        },

        /**
         * @private
         * @function
         * @name pc.BundleRegistry#canLoadUrl
         * @description Returns true if there is a bundle that contains the specified URL
         * and that bundle is either loaded or currently being loaded.
         * @param {String} url The url
         * @returns {Boolean} True or false
         */
        canLoadUrl: function (url) {
            return !!this._findLoadedOrLoadingBundleForUrl(url);
        },

        /**
         * @private
         * @function
         * @name pc.BundleRegistry#loadUrl
         * @description Loads the specified file URL from a bundle that is either loaded or currently being loaded.
         * @param {String} url The URL. Make sure you are using a relative URL that does not contain any query parameters.
         * @param {Function} callback The callback is called when the file has been loaded or if an error occures. The callback
         * expects the first argment to be the error message (if any) and the second argument is the file blob URL.
         * @example
         * var url = asset.getFileUrl().split('?')[0]; // get normalized asset URL
         * this.app.bundles.loadFile(url, function (err, blobUrl) {
         *     // do something with the blob URL
         * });
         */
        loadUrl: function (url, callback) {
            var bundle = this._findLoadedOrLoadingBundleForUrl(url);
            if (! bundle) {
                callback('URL ' + url + ' not found in any bundles');
                return;
            }

            // Only load files from bundles that're explicilty requested to be loaded.
            if (bundle.loaded) {
                callback(null, bundle.resource.getBlobUrl(decodeURIComponent(url)));
            } else if (this._fileRequests.hasOwnProperty(url)) {
                this._fileRequests[url].push(callback);
            } else {
                this._fileRequests[url] = [callback];
            }
        },

        /**
         * @private
         * @function
         * @name pc.ResourceLoader#destroy
         * @description Destroys the registry, and releases its resources. Does not unload bundle assets
         * as these should be unloaded by the {@link pc.AssetRegistry}.
         */
        destroy: function () {
            this._assets.off('add', this._onAssetAdded, this);
            this._assets.off('remove', this._onAssetRemoved, this);

            for (var id in this._bundleAssets) {
                this._unregisterBundleEventListeners(id);
            }

            this._assets = null;
            this._bundleAssets = null;
            this._assetsInBundles = null;
            this._urlsInBundles = null;
            this._fileRequests = null;
        }
    });

    return {
        BundleRegistry: BundleRegistry
    };
}());
<commit_msg>Bundle registry fixes<commit_after>Object.assign(pc, function () {
    'use strict';

    /**
     * @private
     * @constructor
     * @name pc.BundleRegistry
     * @param {pc.AssetRegistry} assets The asset registry
     * @classdesc Keeps track of which assets are in bundles and loads files from bundles.
     */
    var BundleRegistry = function (assets) {
        this._assets = assets;

        // index of bundle assets
        this._bundleAssets = {};
        // index asset id to one more bundle assets
        this._assetsInBundles = {};
        // index file urls to one or more bundle assets
        this._urlsInBundles = {};
        // contains requests to load file URLs indexed by URL
        this._fileRequests = {};

        this._assets.on('add', this._onAssetAdded, this);
        this._assets.on('remove', this._onAssetRemoved, this);
    };

    Object.assign(BundleRegistry.prototype, {
        // Add asset in internal indexes
        _onAssetAdded: function (asset) {
            // if this is a bundle asset then add it and
            // index its referenced assets
            if (asset.type === 'bundle') {
                this._bundleAssets[asset.id] = asset;

                this._registerBundleEventListeners(asset.id);

                for (var i = 0, len = asset.data.assets.length; i < len; i++) {
                    this._indexAssetInBundle(asset.data.assets[i], asset);
                }
            } else {
                // if this is not a bundle then index its URLs
                if (this._assetsInBundles[asset.id]) {
                    this._indexAssetFileUrls(asset);
                }
            }
        },

        _registerBundleEventListeners: function (bundleAssetId) {
            this._assets.on('load:' + bundleAssetId, this._onBundleLoaded, this);
            this._assets.on('error:' + bundleAssetId, this._onBundleError, this);
        },

        _unregisterBundleEventListeners: function (bundleAssetId) {
            this._assets.off('load:' + bundleAssetId, this._onBundleLoaded, this);
            this._assets.off('error:' + bundleAssetId, this._onBundleError, this);
        },

        // Index the specified asset id and its file URLs so that
        // the registry knows that the asset is in that bundle
        _indexAssetInBundle: function (assetId, bundleAsset) {
            if (! this._assetsInBundles[assetId]) {
                this._assetsInBundles[assetId] = [bundleAsset];
            } else {
                var bundles = this._assetsInBundles[assetId];
                var idx = bundles.indexOf(bundleAsset);
                if (idx === -1) {
                    bundles.push(bundleAsset);
                }
            }

            var asset = this._assets.get(assetId);
            if (asset) {
                this._indexAssetFileUrls(asset);
            }
        },

        // Index the file URLs of the specified asset
        _indexAssetFileUrls: function (asset) {
            var urls = this._getAssetFileUrls(asset);
            if (! urls) return;

            for (var i = 0, len = urls.length; i < len; i++) {
                var url = urls[i];
                // Just set the URL to point to the same bundles as the asset does.
                // This is a performance/memory optimization and it assumes that
                // the URL will not exist in any other asset. If that does happen then
                // this will not work as expected if the asset is removed, as the URL will
                // be removed too.
                this._urlsInBundles[url] = this._assetsInBundles[asset.id];
            }
        },

        // Get all the possible URLs of an asset
        _getAssetFileUrls: function (asset) {
            var url = asset.getFileUrl();
            if (! url) return null;

            url = this._normalizeUrl(url);
            var urls = [url];

            // a font might have additional files
            // so add them in the list
            if (asset.type === 'font') {
                var numFiles = asset.data.info.maps.length;
                for (var i = 1; i < numFiles; i++) {
                    urls.push(url.replace('.png', i + '.png'));
                }
            }

            return urls;
        },

        // Removes query parameters from a URL
        _normalizeUrl: function (url) {
            return url && url.split('?')[0];
        },

        // Remove asset from internal indexes
        _onAssetRemoved: function (asset) {
            if (asset.type === 'bundle') {
                // remove bundle from index
                delete this._bundleAssets[asset.id];

                // remove event listeners
                this._unregisterBundleEventListeners(asset.id);

                // remove bundle from _assetsInBundles and _urlInBundles indexes
                var idx, id;
                for (id in this._assetsInBundles) {
                    var array = this._assetsInBundles[id];
                    idx = array.indexOf(asset);
                    if (idx !== -1) {
                        array.splice(idx, 1);
                        if (! array.length) {
                            delete this._assetsInBundles[id];

                            // make sure we do not leave that array in
                            // any _urlInBundles entries
                            for (var url in this._urlsInBundles) {
                                if (this._urlsInBundles[url] === array) {
                                    delete this._urlsInBundles[url];
                                }
                            }
                        }
                    }
                }

                // fail any pending requests for this bundle
                this._onBundleError('Bundle ' + asset.id + ' was removed', asset);

            } else if (this._assetsInBundles[asset.id]) {
                // remove asset from _assetInBundles
                delete this._assetsInBundles[asset.id];

                // remove asset urls from _urlsInBundles
                var urls = this._getAssetFileUrls(asset);
                for (var i = 0, len = urls.length; i < len; i++) {
                    delete this._urlsInBundles[urls[i]];
                }
            }

        },

        // If we have any pending file requests
        // that can be satisfied by the specified bundle
        // then resolve them
        _onBundleLoaded: function (bundleAsset) {
            // this can happen if the bundleAsset failed
            // to create its resource
            if (! bundleAsset.resource) {
                this._onBundleError('Bundle ' + bundleAsset.id + ' failed to load', bundleAsset);
                return;
            }

            // on next tick resolve the pending asset requests
            // don't do it on the same tick because that ties the loading
            // of the bundle to the loading of all the assets
            requestAnimationFrame(function () {
                for (var url in this._fileRequests) {
                    var bundles = this._urlsInBundles[url];
                    if (!bundles || bundles.indexOf(bundleAsset) === -1) continue;

                    var decodedUrl = decodeURIComponent(url);
                    var err = null;
                    if (!bundleAsset.resource.hasBlobUrl(decodedUrl)) {
                        err = 'Bundle ' + bundleAsset.id + ' does not contain URL ' + url;
                    }

                    var requests = this._fileRequests[url];
                    for (var i = 0, len = requests.length; i < len; i++) {
                        if (err) {
                            requests[i](err);
                        } else {
                            requests[i](null, bundleAsset.resource.getBlobUrl(decodedUrl));
                        }
                    }

                    delete this._fileRequests[url];
                }
            }.bind(this));
        },

        // If we have outstanding file requests for any
        // of the URLs in the specified bundle then search for
        // other bundles that can satisfy these requests.
        // If we do not find any other bundles then fail
        // those pending file requests with the specified error.
        _onBundleError: function (err, bundleAsset) {
            for (var url in this._fileRequests) {
                var bundle = this._findLoadedOrLoadingBundleForUrl(url);
                if (! bundle) {
                    var requests = this._fileRequests[url];
                    for (var i = 0, len = requests.length; i < len; i++) {
                        requests[i](err);
                    }

                    delete this._fileRequests[url];

                }
            }
        },

        // Finds a bundle that contains the specified URL but
        // only returns the bundle if it's either loaded or being loaded
        _findLoadedOrLoadingBundleForUrl: function (url) {
            var bundles = this._urlsInBundles[url];
            if (! bundles) return null;

            // look for loaded bundle first...
            var len = bundles.length;
            var i;
            for (i = 0; i < len; i++) {
                // 'loaded' can be true but if there was an error
                // then 'resource' would be null
                if (bundles[i].loaded && bundles[i].resource) {
                    return bundles[i];
                }
            }

            // ...then look for loading bundles
            for (i = 0; i < len; i++) {
                if (bundles[i].loading) {
                    return bundles[i];
                }
            }

            return null;
        },

        /**
         * @private
         * @function
         * @name pc.BundleRegistry#listBundlesForAsset
         * @description Lists all of the available bundles that reference the specified asset id.
         * @param {pc.Asset} asset The asset
         * @returns {pc.Asset[]} An array of bundle assets.
         */
        listBundlesForAsset: function (asset) {
            var bundles = this._assetsInBundles[asset.id];
            if (bundles) {
                return bundles.slice();
            }

            return [];
        },

        /**
         * @private
         * @function
         * @name pc.BundleRegistry#list
         * @description Lists all of the available bundles. This includes bundles that are not loaded.
         * @returns {pc.Asset[]} An array of bundle assets.
         */
        list: function () {
            var result = [];
            for (var id in this._bundleAssets) {
                result.push(this._bundleAssets[id]);
            }

            return result;
        },

        /**
         * @private
         * @function
         * @name pc.BundleRegistry#hasUrl
         * @description Returns true if there is a bundle that contains the specified URL
         * @param {String} url The url
         * @returns {Boolean} True or false
         */
        hasUrl: function (url) {
            return !!this._urlsInBundles[url];
        },

        /**
         * @private
         * @function
         * @name pc.BundleRegistry#canLoadUrl
         * @description Returns true if there is a bundle that contains the specified URL
         * and that bundle is either loaded or currently being loaded.
         * @param {String} url The url
         * @returns {Boolean} True or false
         */
        canLoadUrl: function (url) {
            return !!this._findLoadedOrLoadingBundleForUrl(url);
        },

        /**
         * @private
         * @function
         * @name pc.BundleRegistry#loadUrl
         * @description Loads the specified file URL from a bundle that is either loaded or currently being loaded.
         * @param {String} url The URL. Make sure you are using a relative URL that does not contain any query parameters.
         * @param {Function} callback The callback is called when the file has been loaded or if an error occures. The callback
         * expects the first argment to be the error message (if any) and the second argument is the file blob URL.
         * @example
         * var url = asset.getFileUrl().split('?')[0]; // get normalized asset URL
         * this.app.bundles.loadFile(url, function (err, blobUrl) {
         *     // do something with the blob URL
         * });
         */
        loadUrl: function (url, callback) {
            var bundle = this._findLoadedOrLoadingBundleForUrl(url);
            if (! bundle) {
                callback('URL ' + url + ' not found in any bundles');
                return;
            }

            // Only load files from bundles that're explicilty requested to be loaded.
            if (bundle.loaded) {
                var decodedUrl = decodeURIComponent(url);
                if (!bundle.resource.hasBlobUrl(decodedUrl)) {
                    callback('Bundle ' + bundle.id + ' does not contain URL ' + url);
                    return;
                }

                callback(null, bundle.resource.getBlobUrl(decodedUrl));
            } else if (this._fileRequests.hasOwnProperty(url)) {
                this._fileRequests[url].push(callback);
            } else {
                this._fileRequests[url] = [callback];
            }
        },

        /**
         * @private
         * @function
         * @name pc.ResourceLoader#destroy
         * @description Destroys the registry, and releases its resources. Does not unload bundle assets
         * as these should be unloaded by the {@link pc.AssetRegistry}.
         */
        destroy: function () {
            this._assets.off('add', this._onAssetAdded, this);
            this._assets.off('remove', this._onAssetRemoved, this);

            for (var id in this._bundleAssets) {
                this._unregisterBundleEventListeners(id);
            }

            this._assets = null;
            this._bundleAssets = null;
            this._assetsInBundles = null;
            this._urlsInBundles = null;
            this._fileRequests = null;
        }
    });

    return {
        BundleRegistry: BundleRegistry
    };
}());
<|endoftext|>


<commit_before>jfxrApp.directive('canvasManager', [function() {
  return {
    controller: ['$element', function($element) {
      var canvas = $element[0];
      var context = canvas.getContext('2d');
      var width = 0;
      var height = 0;
      var drawFunctions = [];

      this.registerDrawFunction = function(drawFunction) {
        drawFunctions.push(drawFunction);
      };

      this.draw = function() {
        width = canvas.clientWidth;
        height = canvas.clientHeight;
        if (canvas.width != width) {
          canvas.width = width;
        }
        if (canvas.height != height) {
          canvas.height = height;
        }

        context.globalAlpha = 1.0;
        context.clearRect(0, 0, width, height);

        for (var i = 0; i < drawFunctions.length; i++) {
          drawFunctions[i](context, width, height);
        }
      };
    }],
  };
}]);

jfxrApp.directive('waveshape', [function() {
  return {
    require: 'canvasManager',
    link: function(scope, element, attrs, ctrl) {
      var buffer = null;

      ctrl.registerDrawFunction(function(context, width, height) {
        if (!buffer) return;

        var channel = buffer.getChannelData(0);
        var numSamples = buffer.length;

        context.strokeStyle = '#fff';
        context.globalAlpha = 0.1;
        context.lineWidth = 1.0;
        context.beginPath();
        context.moveTo(0, height / 2);
        context.lineTo(width, height / 2);
        context.stroke();

        context.strokeStyle = '#57d';
        context.globalAlpha = 1.0;

        var i;
        var sample;

        if (numSamples < width) {
          // Draw a line between each pair of successive samples.
          context.beginPath();
          for (i = 0; i < numSamples; i++) {
            sample = channel[i];
            context.lineTo(i / numSamples * width, (1 - sample) * height / 2);
          }
          context.stroke();
        } else {
          // More samples than pixels. At a 5s buffer, drawing all samples
          // takes 300ms. For performance, draw a vertical line in each pixel
          // column, representing the range of samples falling into this
          // column.
          // TODO: make this look smoother by taking advantage of antialiasing somehow
          for (var x = 0; x < width; x++) {
            var min = 1e99, max = -1e99;
            var start = Math.floor(x / width * numSamples);
            var end = Math.ceil((x + 1) / width * numSamples);
            for (i = start; i < end; i++) {
              sample = channel[i];
              if (sample < min) min = sample;
              if (sample > max) max = sample;
            }
            context.beginPath();
            context.moveTo(x + 0.5, (1 - min) * height / 2 - 0.5);
            context.lineTo(x + 0.5, (1 - max) * height / 2 + 0.5);
            context.stroke();
          }
        }
      });

      scope.$watch(attrs.waveshape, function(value) {
        buffer = value;
        ctrl.draw();
      });
    },
  };
}]);

jfxrApp.directive('drawAmplitude', [function() {
  return {
    require: 'canvasManager',
    link: function(scope, element, attrs, ctrl) {
      var sound = null;

      ctrl.registerDrawFunction(function(context, width, height) {
        if (!sound) return;

        var duration = sound.duration();
        var baseY = height - 0.5;
        var scaleY = -(height - 1) / (1 + sound.sustainPunch.value / 100);

        context.strokeStyle = '#d66';
        context.globalAlpha = 1.0;
        context.lineWidth = 1.0;
        context.beginPath();
        for (var x = 0; x < width; x++) {
          var time = x / width * duration;
          context.lineTo(x, baseY + sound.amplitudeAt(time) * scaleY);
        }
        context.stroke();
      });

      scope.$watch(attrs.drawAmplitude + '.serialize()', function(value) {
        sound = scope.$eval(attrs.drawAmplitude);
        ctrl.draw();
      });
    },
  };
}]);

jfxrApp.directive('drawFrequency', [function() {
  return {
    require: 'canvasManager',
    link: function(scope, element, attrs, ctrl) {
      var sound = null;

      ctrl.registerDrawFunction(function(context, width, height) {
        if (!sound) return;

        var duration = sound.duration();

        var min = 0;
        var max = 0;
        for (var x = 0; x < width; x++) {
          var f = sound.frequencyAt(x / width * duration);
          max = Math.max(max, f);
        }
        var baseY;
        var scaleY;
        if (max - min > 0) {
          scaleY = -(height - 1) / (max - min);
          baseY = height - 0.5 - min * scaleY;
        } else {
          scaleY = 0;
          baseY = height / 2;
        }

        context.strokeStyle = '#bb5';
        context.globalAlpha = 1.0;
        context.lineWidth = 1.0;
        context.beginPath();
        for (var x = 0; x < width; x++) {
          var time = x / width * duration;
          context.lineTo(x, baseY + sound.frequencyAt(time) * scaleY);
        }
        context.stroke();
      });

      scope.$watch(attrs.drawFrequency + '.serialize()', function(value) {
        sound = scope.$eval(attrs.drawFrequency);
        ctrl.draw();
      });
    },
  };
}]);
<commit_msg>Unlint<commit_after>jfxrApp.directive('canvasManager', [function() {
  return {
    controller: ['$element', function($element) {
      var canvas = $element[0];
      var context = canvas.getContext('2d');
      var width = 0;
      var height = 0;
      var drawFunctions = [];

      this.registerDrawFunction = function(drawFunction) {
        drawFunctions.push(drawFunction);
      };

      this.draw = function() {
        width = canvas.clientWidth;
        height = canvas.clientHeight;
        if (canvas.width != width) {
          canvas.width = width;
        }
        if (canvas.height != height) {
          canvas.height = height;
        }

        context.globalAlpha = 1.0;
        context.clearRect(0, 0, width, height);

        for (var i = 0; i < drawFunctions.length; i++) {
          drawFunctions[i](context, width, height);
        }
      };
    }],
  };
}]);

jfxrApp.directive('waveshape', [function() {
  return {
    require: 'canvasManager',
    link: function(scope, element, attrs, ctrl) {
      var buffer = null;

      ctrl.registerDrawFunction(function(context, width, height) {
        if (!buffer) return;

        var channel = buffer.getChannelData(0);
        var numSamples = buffer.length;

        context.strokeStyle = '#fff';
        context.globalAlpha = 0.1;
        context.lineWidth = 1.0;
        context.beginPath();
        context.moveTo(0, height / 2);
        context.lineTo(width, height / 2);
        context.stroke();

        context.strokeStyle = '#57d';
        context.globalAlpha = 1.0;

        var i;
        var sample;

        if (numSamples < width) {
          // Draw a line between each pair of successive samples.
          context.beginPath();
          for (i = 0; i < numSamples; i++) {
            sample = channel[i];
            context.lineTo(i / numSamples * width, (1 - sample) * height / 2);
          }
          context.stroke();
        } else {
          // More samples than pixels. At a 5s buffer, drawing all samples
          // takes 300ms. For performance, draw a vertical line in each pixel
          // column, representing the range of samples falling into this
          // column.
          // TODO: make this look smoother by taking advantage of antialiasing somehow
          for (var x = 0; x < width; x++) {
            var min = 1e99, max = -1e99;
            var start = Math.floor(x / width * numSamples);
            var end = Math.ceil((x + 1) / width * numSamples);
            for (i = start; i < end; i++) {
              sample = channel[i];
              if (sample < min) min = sample;
              if (sample > max) max = sample;
            }
            context.beginPath();
            context.moveTo(x + 0.5, (1 - min) * height / 2 - 0.5);
            context.lineTo(x + 0.5, (1 - max) * height / 2 + 0.5);
            context.stroke();
          }
        }
      });

      scope.$watch(attrs.waveshape, function(value) {
        buffer = value;
        ctrl.draw();
      });
    },
  };
}]);

jfxrApp.directive('drawAmplitude', [function() {
  return {
    require: 'canvasManager',
    link: function(scope, element, attrs, ctrl) {
      var sound = null;

      ctrl.registerDrawFunction(function(context, width, height) {
        if (!sound) return;

        var duration = sound.duration();
        var baseY = height - 0.5;
        var scaleY = -(height - 1) / (1 + sound.sustainPunch.value / 100);

        context.strokeStyle = '#d66';
        context.globalAlpha = 1.0;
        context.lineWidth = 1.0;
        context.beginPath();
        for (var x = 0; x < width; x++) {
          var time = x / width * duration;
          context.lineTo(x, baseY + sound.amplitudeAt(time) * scaleY);
        }
        context.stroke();
      });

      scope.$watch(attrs.drawAmplitude + '.serialize()', function(value) {
        sound = scope.$eval(attrs.drawAmplitude);
        ctrl.draw();
      });
    },
  };
}]);

jfxrApp.directive('drawFrequency', [function() {
  return {
    require: 'canvasManager',
    link: function(scope, element, attrs, ctrl) {
      var sound = null;

      ctrl.registerDrawFunction(function(context, width, height) {
        if (!sound) return;

        var duration = sound.duration();

        var min = 0;
        var max = 0;
        var x;
        for (x = 0; x < width; x++) {
          var f = sound.frequencyAt(x / width * duration);
          max = Math.max(max, f);
        }
        var baseY;
        var scaleY;
        if (max - min > 0) {
          scaleY = -(height - 1) / (max - min);
          baseY = height - 0.5 - min * scaleY;
        } else {
          scaleY = 0;
          baseY = height / 2;
        }

        context.strokeStyle = '#bb5';
        context.globalAlpha = 1.0;
        context.lineWidth = 1.0;
        context.beginPath();
        for (x = 0; x < width; x++) {
          var time = x / width * duration;
          context.lineTo(x, baseY + sound.frequencyAt(time) * scaleY);
        }
        context.stroke();
      });

      scope.$watch(attrs.drawFrequency + '.serialize()', function(value) {
        sound = scope.$eval(attrs.drawFrequency);
        ctrl.draw();
      });
    },
  };
}]);
<|endoftext|>


<commit_before>import m from 'mithril';
import _ from 'underscore';
import I18n from 'i18n-js';
import h from '../h';
import moment from 'moment';
import models from '../models';
import {
    catarse
} from '../api';
import contributionVM from '../vms/contribution-vm';
import commonPaymentVM from '../vms/common-payment-vm';
import ownerMessageContent from '../c/owner-message-content';
import subscriptionStatusIcon from '../c/subscription-status-icon';
import paymentMethodIcon from '../c/payment-method-icon';
import cancelSubscriptionContent from '../c/cancel-subscription-content';
import modalBox from '../c/modal-box';
import userVM from '../vms/user-vm';

const I18nScope = _.partial(h.i18nScope, 'payment.state');
const contributionScope = _.partial(h.i18nScope, 'users.contribution_row');

const userSubscriptionBox = {
    controller(args) {
        const subscription = args.subscription,
            displayModal = h.toggleProp(false, true),
            displayCancelModal = h.toggleProp(false, true),
            contactModalInfo = m.prop({});

        const filterProjVM = catarse.filtersVM({
                project_id: 'eq'
            }).project_id(subscription.project_external_id),
            lProj = catarse.loaderWithToken(models.project.getRowOptions(filterProjVM.parameters()));

        lProj.load().then((arr) => {
            subscription.project = arr[0];
            contactModalInfo({
                id: subscription.project.project_user_id,
                name: subscription.project.owner_name,
                project_id: subscription.project.project_id
            });
        });

        if (subscription.payment_method === 'boleto' && subscription.last_payment_id) {
            commonPaymentVM.paymentInfo(subscription.last_payment_id).then((info) => {
                subscription.boleto_url = info.boleto_url;
                subscription.boleto_expiration_date = info.boleto_expiration_date;
                subscription.payment_status = info.status;
            });
        }

        if (subscription.reward_external_id) {
            const filterRewVM = catarse.filtersVM({
                    id: 'eq'
                }).id(subscription.reward_external_id),
                lRew = catarse.loaderWithToken(models.rewardDetail.getRowOptions(filterRewVM.parameters()));

            lRew.load().then((arr) => {
                subscription.reward = arr[0];
            });
        }

        const showLastSubscriptionVersionValueIfHasOne = () => {
            const current_paid_subscription = subscription.current_paid_subscription;
            // has some subscription edition
            if (current_paid_subscription && current_paid_subscription.amount != subscription.checkout_data.amount)
            {
                const paid_value = parseFloat(current_paid_subscription.amount) / 100;
                const next_value = parseFloat(subscription.checkout_data.amount) / 100;
                return [
                    `R$ ${h.formatNumber(paid_value)} por mês`,
                    m('span.badge.badge-attention', [
                        m('span.fa.fa-arrow-right', ''),
                        m.trust(' '),
                        `R$ ${h.formatNumber(next_value)}`,
                    ])
                ];
            }
            else
            {
                const paid_value = parseFloat(subscription.checkout_data.amount) / 100;
                return [`R$ ${h.formatNumber(paid_value)} por mês`];
            }

            return '';
        };

        const showLastSubscriptionVersionPaymentMethodIfHasOne = () => {
            const current_paid_subscription = subscription.current_paid_subscription;

            if (current_paid_subscription && subscription.checkout_data.payment_method != current_paid_subscription.payment_method)
            {
                return [
                    m(subscriptionStatusIcon, { subscription}),
                    m.trust('   '),
                    m(paymentMethodIcon, { subscription : current_paid_subscription}),
                    m('span.badge.badge-attention.fontweight-semibold', [
                        m('span.fa.fa-arrow-right', ''),
                        m.trust(' '),
                        m(paymentMethodIcon, { subscription })
                    ])
                ];
            }
            else
            {
                return [
                    m(subscriptionStatusIcon, { subscription }),
                    m.trust('   '),
                    m(paymentMethodIcon, { subscription })
                ];
            }

            return '';
        };

        const showLastSubscriptionVersionRewardTitleIfHasOne = () => {
            const current_paid_subscription = subscription.current_paid_subscription;
            const current_reward_data = subscription.current_reward_data;
            const current_reward_id = subscription.current_reward_id;

            // first selection was no reward, but now selected one
            if (!current_reward_data && subscription.reward)
            {
                return [
                    ` ${I18n.t('no_reward', contributionScope())} `,
                    m.trust(' '),
                    m('.fontsize-smallest.fontweight-semibold',
                      m('span.badge.badge-attention', [
                          m('span.fa.fa-arrow-right', ''),
                          m.trust(' '),
                          subscription.reward.title
                      ]))
                ];
            }
            else if (current_reward_data && subscription.reward && subscription.reward.id != current_reward_id)
            {
                const reward_description_formated = h.simpleFormat(`${current_reward_data.description.substring(0, 90)} (...)`);
                return [
                    m('.fontsize-smallest.fontweight-semibold', current_reward_data.title),
                    m('p.fontcolor-secondary.fontsize-smallest', m.trust(reward_description_formated)),
			              m('.fontsize-smallest.fontweight-semibold',
                      m('span.badge.badge-attention', [
                          m('span.fa.fa-arrow-right', ''),
                          m.trust(' '),
                          subscription.reward.title
                      ]))
                ];
            }
            else if (subscription.reward)
            {
                const reward_description = subscription.reward.description.substring(0, 90);
                const reward_description_formated = h.simpleFormat(`${reward_description} (...)`);
                return [
                    m('.fontsize-smallest.fontweight-semibold', subscription.reward.title),
                    m('p.fontcolor-secondary.fontsize-smallest', m.trust(reward_description_formated))
                ];
            }
            else
            {
                return [
                    subscription.reward_external_id ? null : ` ${I18n.t('no_reward', contributionScope())} `
                ];
            }
        };

        const showLastSubscriptionVersionEditionNextCharge = () => {
            const current_reward_data = subscription.current_reward_data;
            const current_reward_id = subscription.current_reward_id;
            const current_paid_subscription = subscription.current_paid_subscription;

            if (current_paid_subscription &&
                (
                    subscription.reward_id != current_reward_id ||
                    subscription.checkout_data.payment_method != current_paid_subscription.payment_method ||
                    subscription.checkout_data.amount != current_paid_subscription.amount
                )
            ) {
                const message = `As alterações destacadas entrarão em vigor na próxima cobrança ${h.momentify(subscription.next_charge_at, 'DD/MM/YYYY')}.`;
                return m('.card-alert.fontsize-smaller.fontweight-semibold.u-marginbottom-10.u-radius', [
                    m('span.fa.fa-exclamation-triangle', ''),
                    m.trust(' '),
                    message
                ]);
            }

            return '';
        };

        return {
            toggleAnonymous: userVM.toggleAnonymous,
            displayModal,
            displayCancelModal,
            subscription,
            contactModalInfo,
            showLastSubscriptionVersionValueIfHasOne,
            showLastSubscriptionVersionPaymentMethodIfHasOne,
            showLastSubscriptionVersionRewardTitleIfHasOne,
            showLastSubscriptionVersionEditionNextCharge
        };
    },
    view(ctrl) {
        const subscription = ctrl.subscription;

        return (!_.isEmpty(subscription) && !_.isEmpty(subscription.project) ? m('div',
            (ctrl.displayCancelModal() && !_.isEmpty(ctrl.contactModalInfo()) ?
                m.component(modalBox, {
                    displayModal: ctrl.displayCancelModal,
                    content: [cancelSubscriptionContent, {
                        displayModal: ctrl.displayCancelModal,
                        subscription
                    }]
                }) : ''
            ),
            (ctrl.displayModal() && !_.isEmpty(ctrl.contactModalInfo()) ?
                m.component(modalBox, {
                    displayModal: ctrl.displayModal,
                    content: [ownerMessageContent, ctrl.contactModalInfo]
                }) : ''
            ), [
                m('.card.w-row', [
                    m('.u-marginbottom-20.w-col.w-col-3', [
                        m('.u-marginbottom-10.w-row', [
                            m('.u-marginbottom-10.w-col.w-col-4',
                                m(`a.w-inline-block[href='/${subscription.project.permalink}']`,
                                    m(`img.thumb-project.u-radius[alt='${subscription.project.project_name}'][src='${subscription.project.project_img}'][width='50']`)
                                )
                            ),
                            m('.w-col.w-col-8',
                                m('.fontsize-small.fontweight-semibold.lineheight-tight', [
                                    m(`a.link-hidden[href='/${subscription.project.permalink}']`,
                                        subscription.project.project_name
                                    ),
                                    m('img[alt="Badge Assinatura"][src="/assets/catarse_bootstrap/badge-sub-h.png"]')
                                ])
                            )
                        ]),
                        m("a.btn.btn-edit.btn-inline.btn-small.w-button[href='javascript:void(0);']", {
                            onclick: () => {
                                ctrl.displayModal.toggle();
                            }
                        },
                            I18n.t('contact_author', contributionScope())
                        )
                    ]),
                    m('.u-marginbottom-20.w-col.w-col-3', [
                        m('.fontsize-base.fontweight-semibold.lineheight-tighter', ctrl.showLastSubscriptionVersionValueIfHasOne()),
                        m('.fontcolor-secondary.fontsize-smaller.fontweight-semibold',
                            `Iniciou há ${moment(subscription.created_at).locale('pt').fromNow(true)}`
                        ),
                        m('.u-marginbottom-10', ctrl.showLastSubscriptionVersionPaymentMethodIfHasOne())
                    ]),
                    m('.u-marginbottom-20.w-col.w-col-3', ctrl.showLastSubscriptionVersionRewardTitleIfHasOne()),
                    m('.u-marginbottom-10.u-text-center.w-col.w-col-3',
                        (subscription.status === 'started' ? [
                            m('.card-alert.fontsize-smaller.fontweight-semibold.u-marginbottom-10.u-radius', [
                                m('span.fa.fa-exclamation-triangle'),
                                m.trust(' '),
                                'Aguardando confirmação do pagamento'
                            ]),
                                (subscription.boleto_url ? m(`a.btn.btn-inline.btn-small.w-button[target=_blank][href=${subscription.boleto_url}]`, 'Imprimir boleto') : null)
                        ] :
                            (subscription.status === 'inactive' ? [
                                (subscription.payment_status === 'pending'
                                    && subscription.boleto_url
                                    && subscription.boleto_expiration_date ? [
                                        m('.card-alert.fontsize-smaller.fontweight-semibold.u-marginbottom-10.u-radius', [
                                            m('span.fa.fa-exclamation-triangle'),
                                            ` O boleto de sua assinatura vence dia ${h.momentify(subscription.boleto_expiration_date)}`
                                        ]),
                                        m(`a.btn.btn-inline.btn-small.w-button[target=_blank][href=${subscription.boleto_url}]`, 'Imprimir boleto')
                                    ] : [
                                        m('.card-alert.fontsize-smaller.fontweight-semibold.u-marginbottom-10.u-radius', [
                                            m('span.fa.fa-exclamation-triangle'),
                                            m.trust(' '),
                                            'Sua assinatura está inativa por falta de pagamento'
                                        ]),
                                        m(`a.btn.btn-inline.btn-small.w-button[target=_blank][href=/projects/${subscription.project_external_id}/subscriptions/start?subscription_id=${subscription.id}${subscription.reward_external_id ? `&reward_id=${subscription.reward_external_id}` : ''}&subscription_status=${subscription.status}]`, 'Assinar novamente')
                                    ])
                            ] : subscription.status === 'canceled' && subscription.project.status == 'online' ? [
                                m('a.btn.btn-terciary.u-marginbottom-20.btn-inline.w-button',
                                        { href: `/projects/${subscription.project_external_id}/subscriptions/start?subscription_id=${subscription.id}${subscription.reward_external_id ? `&reward_id=${subscription.reward_external_id}` : ''}&subscription_status=${subscription.status}` },
                                        'Reativar assinatura'
                                    ),
                                m('.card-error.fontsize-smaller.fontweight-semibold.u-marginbottom-10.u-radius', [
                                    m('span.fa.fa-exclamation-triangle'),
                                    m.trust(' '),
                                    ' Você cancelou sua assinatura'
                                ])
                            ] : subscription.status === 'canceling' ?
                                m('.u-radius.fontsize-smaller.u-marginbottom-10.fontweight-semibold.card-error',
                                    m('div', [
                                        m('span.fa.fa-exclamation-triangle',
                                            ' '
                                        ),
                                        ` Sua assinatura será cancelada no dia ${h.momentify(subscription.next_charge_at, 'DD/MM/YYYY')}. Até lá, ela ainda será considerada ativa.`
                                    ])
                                ) : (subscription.status === 'active' ? [
                                    ctrl.showLastSubscriptionVersionEditionNextCharge(),
                                    subscription.payment_status !== 'pending' ? m('a.btn.btn-terciary.u-marginbottom-20.btn-inline.w-button',
                                        { href: `/projects/${subscription.project_external_id}/subscriptions/start?${subscription.reward_external_id ? `reward_id=${subscription.reward_external_id}` : ''}&subscription_id=${subscription.id}&subscription_status=${subscription.status}` },
                                        'Editar assinatura'
                                    ) : '',
                                    subscription.payment_status === 'pending'
                                    && subscription.boleto_url
                                    && subscription.boleto_expiration_date ?
                                    [
                                        moment(subscription.boleto_expiration_date).add(1, 'days').isBefore(Date.now())
                                            ? m('.card-alert.fontsize-smaller.fontweight-semibold.u-marginbottom-10.u-radius', [
                                                m('span.fa.fa-exclamation-triangle'),
                                                ` O boleto de sua assinatura venceu dia ${h.momentify(subscription.boleto_expiration_date)}`
                                            ])
                                            : [
                                                m('.card-alert.fontsize-smaller.fontweight-semibold.u-marginbottom-10.u-radius', [
                                                    m('span.fa.fa-exclamation-triangle'),
                                                    ` O boleto de sua assinatura vence dia ${h.momentify(subscription.boleto_expiration_date)}`
                                                ]),
                                                m(`a.btn.btn-inline.btn-small.u-marginbottom-20.w-button[target=_blank][href=${subscription.boleto_url}]`, 'Imprimir boleto')
                                            ]
                                    ] : '',
                                    m('button.btn-link.fontsize-smallest.link-hidden-light', {
                                        onclick: () => {
                                            ctrl.displayCancelModal.toggle();
                                        }
                                    },
                                        'Cancelar assinatura'
                                    )
                                ] : null)

                            ))
                    )
                ])
            ]
        ) : m('div', ''));
    }
};

export default userSubscriptionBox;
<commit_msg>fixing showing no reward to some reward transition #155246263<commit_after>import m from 'mithril';
import _ from 'underscore';
import I18n from 'i18n-js';
import h from '../h';
import moment from 'moment';
import models from '../models';
import {
    catarse
} from '../api';
import contributionVM from '../vms/contribution-vm';
import commonPaymentVM from '../vms/common-payment-vm';
import ownerMessageContent from '../c/owner-message-content';
import subscriptionStatusIcon from '../c/subscription-status-icon';
import paymentMethodIcon from '../c/payment-method-icon';
import cancelSubscriptionContent from '../c/cancel-subscription-content';
import modalBox from '../c/modal-box';
import userVM from '../vms/user-vm';

const I18nScope = _.partial(h.i18nScope, 'payment.state');
const contributionScope = _.partial(h.i18nScope, 'users.contribution_row');

const userSubscriptionBox = {
    controller(args) {
        const subscription = args.subscription,
            displayModal = h.toggleProp(false, true),
            displayCancelModal = h.toggleProp(false, true),
            contactModalInfo = m.prop({});

        const filterProjVM = catarse.filtersVM({
                project_id: 'eq'
            }).project_id(subscription.project_external_id),
            lProj = catarse.loaderWithToken(models.project.getRowOptions(filterProjVM.parameters()));

        lProj.load().then((arr) => {
            subscription.project = arr[0];
            contactModalInfo({
                id: subscription.project.project_user_id,
                name: subscription.project.owner_name,
                project_id: subscription.project.project_id
            });
        });

        if (subscription.payment_method === 'boleto' && subscription.last_payment_id) {
            commonPaymentVM.paymentInfo(subscription.last_payment_id).then((info) => {
                subscription.boleto_url = info.boleto_url;
                subscription.boleto_expiration_date = info.boleto_expiration_date;
                subscription.payment_status = info.status;
            });
        }

        if (subscription.reward_external_id) {
            const filterRewVM = catarse.filtersVM({
                    id: 'eq'
                }).id(subscription.reward_external_id),
                lRew = catarse.loaderWithToken(models.rewardDetail.getRowOptions(filterRewVM.parameters()));

            lRew.load().then((arr) => {
                subscription.reward = arr[0];
            });
        }

        const showLastSubscriptionVersionValueIfHasOne = () => {
            const current_paid_subscription = subscription.current_paid_subscription;
            // has some subscription edition
            if (current_paid_subscription && current_paid_subscription.amount != subscription.checkout_data.amount)
            {
                const paid_value = parseFloat(current_paid_subscription.amount) / 100;
                const next_value = parseFloat(subscription.checkout_data.amount) / 100;
                return [
                    `R$ ${h.formatNumber(paid_value)} por mês`,
                    m('span.badge.badge-attention', [
                        m('span.fa.fa-arrow-right', ''),
                        m.trust(' '),
                        `R$ ${h.formatNumber(next_value)}`,
                    ])
                ];
            }
            else
            {
                const paid_value = parseFloat(subscription.checkout_data.amount) / 100;
                return [`R$ ${h.formatNumber(paid_value)} por mês`];
            }

            return '';
        };

        const showLastSubscriptionVersionPaymentMethodIfHasOne = () => {
            const current_paid_subscription = subscription.current_paid_subscription;

            if (current_paid_subscription && subscription.checkout_data.payment_method != current_paid_subscription.payment_method)
            {
                return [
                    m(subscriptionStatusIcon, { subscription}),
                    m.trust('   '),
                    m(paymentMethodIcon, { subscription : current_paid_subscription}),
                    m('span.badge.badge-attention.fontweight-semibold', [
                        m('span.fa.fa-arrow-right', ''),
                        m.trust(' '),
                        m(paymentMethodIcon, { subscription })
                    ])
                ];
            }
            else
            {
                return [
                    m(subscriptionStatusIcon, { subscription }),
                    m.trust('   '),
                    m(paymentMethodIcon, { subscription })
                ];
            }

            return '';
        };

        const showLastSubscriptionVersionRewardTitleIfHasOne = () => {
            const current_paid_subscription = subscription.current_paid_subscription;
            const current_reward_data = subscription.current_reward_data;
            const current_reward_id = subscription.current_reward_id;

            // first selection was no reward, but now selected one
            if (!current_reward_data && subscription.reward)
            {
                return [
                    ` ${I18n.t('no_reward', contributionScope())} `,
                    m.trust(' '),
                    m('.fontsize-smallest.fontweight-semibold',
                      m('span.badge.badge-attention', [
                          m('span.fa.fa-arrow-right', ''),
                          m.trust(' '),
                          subscription.reward.title
                      ]))
                ];
            }
	    // selected one rewared on subscription start, now selected another reward and last and current rewards are different
            else if (current_reward_data && subscription.reward && subscription.reward.id != current_reward_id)
            {
                const reward_description_formated = h.simpleFormat(`${current_reward_data.description.substring(0, 90)} (...)`);
                return [
                    m('.fontsize-smallest.fontweight-semibold', current_reward_data.title),
                    m('p.fontcolor-secondary.fontsize-smallest', m.trust(reward_description_formated)),
			              m('.fontsize-smallest.fontweight-semibold',
                      m('span.badge.badge-attention', [
                          m('span.fa.fa-arrow-right', ''),
                          m.trust(' '),
                          subscription.reward.title
                      ]))
                ];
            }
	    // no edition to rewards yet
            else if (subscription.reward)
            {
                const reward_description = subscription.reward.description.substring(0, 90);
                const reward_description_formated = h.simpleFormat(`${reward_description} (...)`);
                return [
                    m('.fontsize-smallest.fontweight-semibold', subscription.reward.title),
                    m('p.fontcolor-secondary.fontsize-smallest', m.trust(reward_description_formated))
                ];
            }
	    // no editions to reward yet and no reward selected
            else
            {
                return [
                    subscription.reward_external_id ? null : ` ${I18n.t('no_reward', contributionScope())} `
                ];
            }
        };

        const showLastSubscriptionVersionEditionNextCharge = () => {
            const current_reward_data = subscription.current_reward_data;
            const current_reward_id = subscription.current_reward_id;
            const current_paid_subscription = subscription.current_paid_subscription;

            if (current_paid_subscription &&
                (
                    subscription.reward_id != current_reward_id ||
                    subscription.checkout_data.payment_method != current_paid_subscription.payment_method ||
                    subscription.checkout_data.amount != current_paid_subscription.amount
                )
            ) {
                const message = `As alterações destacadas entrarão em vigor na próxima cobrança ${h.momentify(subscription.next_charge_at, 'DD/MM/YYYY')}.`;
                return m('.card-alert.fontsize-smaller.fontweight-semibold.u-marginbottom-10.u-radius', [
                    m('span.fa.fa-exclamation-triangle', ''),
                    m.trust(' '),
                    message
                ]);
            }

            return '';
        };

        return {
            toggleAnonymous: userVM.toggleAnonymous,
            displayModal,
            displayCancelModal,
            subscription,
            contactModalInfo,
            showLastSubscriptionVersionValueIfHasOne,
            showLastSubscriptionVersionPaymentMethodIfHasOne,
            showLastSubscriptionVersionRewardTitleIfHasOne,
            showLastSubscriptionVersionEditionNextCharge
        };
    },
    view(ctrl) {
        const subscription = ctrl.subscription;

        return (!_.isEmpty(subscription) && !_.isEmpty(subscription.project) ? m('div',
            (ctrl.displayCancelModal() && !_.isEmpty(ctrl.contactModalInfo()) ?
                m.component(modalBox, {
                    displayModal: ctrl.displayCancelModal,
                    content: [cancelSubscriptionContent, {
                        displayModal: ctrl.displayCancelModal,
                        subscription
                    }]
                }) : ''
            ),
            (ctrl.displayModal() && !_.isEmpty(ctrl.contactModalInfo()) ?
                m.component(modalBox, {
                    displayModal: ctrl.displayModal,
                    content: [ownerMessageContent, ctrl.contactModalInfo]
                }) : ''
            ), [
                m('.card.w-row', [
                    m('.u-marginbottom-20.w-col.w-col-3', [
                        m('.u-marginbottom-10.w-row', [
                            m('.u-marginbottom-10.w-col.w-col-4',
                                m(`a.w-inline-block[href='/${subscription.project.permalink}']`,
                                    m(`img.thumb-project.u-radius[alt='${subscription.project.project_name}'][src='${subscription.project.project_img}'][width='50']`)
                                )
                            ),
                            m('.w-col.w-col-8',
                                m('.fontsize-small.fontweight-semibold.lineheight-tight', [
                                    m(`a.link-hidden[href='/${subscription.project.permalink}']`,
                                        subscription.project.project_name
                                    ),
                                    m('img[alt="Badge Assinatura"][src="/assets/catarse_bootstrap/badge-sub-h.png"]')
                                ])
                            )
                        ]),
                        m("a.btn.btn-edit.btn-inline.btn-small.w-button[href='javascript:void(0);']", {
                            onclick: () => {
                                ctrl.displayModal.toggle();
                            }
                        },
                            I18n.t('contact_author', contributionScope())
                        )
                    ]),
                    m('.u-marginbottom-20.w-col.w-col-3', [
                        m('.fontsize-base.fontweight-semibold.lineheight-tighter', ctrl.showLastSubscriptionVersionValueIfHasOne()),
                        m('.fontcolor-secondary.fontsize-smaller.fontweight-semibold',
                            `Iniciou há ${moment(subscription.created_at).locale('pt').fromNow(true)}`
                        ),
                        m('.u-marginbottom-10', ctrl.showLastSubscriptionVersionPaymentMethodIfHasOne())
                    ]),
                    m('.u-marginbottom-20.w-col.w-col-3', ctrl.showLastSubscriptionVersionRewardTitleIfHasOne()),
                    m('.u-marginbottom-10.u-text-center.w-col.w-col-3',
                        (subscription.status === 'started' ? [
                            m('.card-alert.fontsize-smaller.fontweight-semibold.u-marginbottom-10.u-radius', [
                                m('span.fa.fa-exclamation-triangle'),
                                m.trust(' '),
                                'Aguardando confirmação do pagamento'
                            ]),
                                (subscription.boleto_url ? m(`a.btn.btn-inline.btn-small.w-button[target=_blank][href=${subscription.boleto_url}]`, 'Imprimir boleto') : null)
                        ] :
                            (subscription.status === 'inactive' ? [
                                (subscription.payment_status === 'pending'
                                    && subscription.boleto_url
                                    && subscription.boleto_expiration_date ? [
                                        m('.card-alert.fontsize-smaller.fontweight-semibold.u-marginbottom-10.u-radius', [
                                            m('span.fa.fa-exclamation-triangle'),
                                            ` O boleto de sua assinatura vence dia ${h.momentify(subscription.boleto_expiration_date)}`
                                        ]),
                                        m(`a.btn.btn-inline.btn-small.w-button[target=_blank][href=${subscription.boleto_url}]`, 'Imprimir boleto')
                                    ] : [
                                        m('.card-alert.fontsize-smaller.fontweight-semibold.u-marginbottom-10.u-radius', [
                                            m('span.fa.fa-exclamation-triangle'),
                                            m.trust(' '),
                                            'Sua assinatura está inativa por falta de pagamento'
                                        ]),
                                        m(`a.btn.btn-inline.btn-small.w-button[target=_blank][href=/projects/${subscription.project_external_id}/subscriptions/start?subscription_id=${subscription.id}${subscription.reward_external_id ? `&reward_id=${subscription.reward_external_id}` : ''}&subscription_status=${subscription.status}]`, 'Assinar novamente')
                                    ])
                            ] : subscription.status === 'canceled' && subscription.project.status == 'online' ? [
                                m('a.btn.btn-terciary.u-marginbottom-20.btn-inline.w-button',
                                        { href: `/projects/${subscription.project_external_id}/subscriptions/start?subscription_id=${subscription.id}${subscription.reward_external_id ? `&reward_id=${subscription.reward_external_id}` : ''}&subscription_status=${subscription.status}` },
                                        'Reativar assinatura'
                                    ),
                                m('.card-error.fontsize-smaller.fontweight-semibold.u-marginbottom-10.u-radius', [
                                    m('span.fa.fa-exclamation-triangle'),
                                    m.trust(' '),
                                    ' Você cancelou sua assinatura'
                                ])
                            ] : subscription.status === 'canceling' ?
                                m('.u-radius.fontsize-smaller.u-marginbottom-10.fontweight-semibold.card-error',
                                    m('div', [
                                        m('span.fa.fa-exclamation-triangle',
                                            ' '
                                        ),
                                        ` Sua assinatura será cancelada no dia ${h.momentify(subscription.next_charge_at, 'DD/MM/YYYY')}. Até lá, ela ainda será considerada ativa.`
                                    ])
                                ) : (subscription.status === 'active' ? [
                                    ctrl.showLastSubscriptionVersionEditionNextCharge(),
                                    subscription.payment_status !== 'pending' ? m('a.btn.btn-terciary.u-marginbottom-20.btn-inline.w-button',
                                        { href: `/projects/${subscription.project_external_id}/subscriptions/start?${subscription.reward_external_id ? `reward_id=${subscription.reward_external_id}` : ''}&subscription_id=${subscription.id}&subscription_status=${subscription.status}` },
                                        'Editar assinatura'
                                    ) : '',
                                    subscription.payment_status === 'pending'
                                    && subscription.boleto_url
                                    && subscription.boleto_expiration_date ?
                                    [
                                        moment(subscription.boleto_expiration_date).add(1, 'days').isBefore(Date.now())
                                            ? m('.card-alert.fontsize-smaller.fontweight-semibold.u-marginbottom-10.u-radius', [
                                                m('span.fa.fa-exclamation-triangle'),
                                                ` O boleto de sua assinatura venceu dia ${h.momentify(subscription.boleto_expiration_date)}`
                                            ])
                                            : [
                                                m('.card-alert.fontsize-smaller.fontweight-semibold.u-marginbottom-10.u-radius', [
                                                    m('span.fa.fa-exclamation-triangle'),
                                                    ` O boleto de sua assinatura vence dia ${h.momentify(subscription.boleto_expiration_date)}`
                                                ]),
                                                m(`a.btn.btn-inline.btn-small.u-marginbottom-20.w-button[target=_blank][href=${subscription.boleto_url}]`, 'Imprimir boleto')
                                            ]
                                    ] : '',
                                    m('button.btn-link.fontsize-smallest.link-hidden-light', {
                                        onclick: () => {
                                            ctrl.displayCancelModal.toggle();
                                        }
                                    },
                                        'Cancelar assinatura'
                                    )
                                ] : null)

                            ))
                    )
                ])
            ]
        ) : m('div', ''));
    }
};

export default userSubscriptionBox;
<|endoftext|>


<commit_before>import Graph from "./graph"
import ResourceTile from "./resource-tile"
import BorderTile from "./border-tile"

const size = 37
const ary = []
const graph = new Graph()

// 00-18 are the resource tiles
// 19-36 are the border tiles
for (let i = 0; i < size; i++) {
    const t = i < 19 ? new ResourceTile() : new BorderTile()
    ary.push(t)
    graph.add(t)
}

//
//                21      22      23      24
//
//
//            20      08      09      10      25
//
//
//        19      07      01      02      11      26
//
//
//    36      18      06      00      03      12      27
//
//
//        35      17      05      04      13      28
//
//
//            34      16      15      14      29
//
//
//                33      32      31      30
//
const edges = [
    /* 00 */ [1, 2, 3, 4, 5, 6],
    /* 01 */ [8, 9, 2, 0, 6, 7],
    /* 02 */ [9, 10, 11, 3, 0, 1],
    /* 03 */ [2, 11, 12, 13, 4, 0],
    /* 04 */ [0, 3, 13, 14, 15, 5],
    /* 05 */ [6, 0, 4, 15, 16, 17],
    /* 06 */ [7, 1, 0, 5, 17, 18],
    /* 07 */ [20, 8, 1, 6, 18, 19],
    /* 08 */ [21, 22, 9, 1, 7, 20],
    /* 09 */ [22, 23, 10, 2, 1, 8],
    /* 10 */ [23, 24, 25, 11, 2, 9],
    /* 11 */ [10, 25, 26, 12, 3, 2],
    /* 12 */ [11, 26, 27, 28, 13, 3],
    /* 13 */ [3, 12, 28, 29, 14, 4],
    /* 14 */ [4, 13, 29, 30, 31, 15],
    /* 15 */ [5, 4, 14, 31, 32, 16],
    /* 16 */ [17, 5, 15, 32, 33, 34],
    /* 17 */ [18, 6, 5, 16, 34, 35],
    /* 18 */ [19, 7, 6, 17, 35, 36],
    /* 19 */ [20, 7, 18, 36],
    /* 20 */ [21, 8, 7, 19],
    /* 21 */ [22, 8, 20],
    /* 22 */ [23, 9, 8, 21],
    /* 23 */ [24, 10, 9, 22],
    /* 24 */ [25, 10, 23],
    /* 25 */ [24, 26, 11, 10],
    /* 26 */ [25, 27, 12, 11],
    /* 27 */ [26, 28, 12],
    /* 28 */ [12, 27, 29, 13],
    /* 29 */ [13, 28, 30, 14],
    /* 30 */ [14, 29, 31],
    /* 31 */ [15, 14, 30, 32],
    /* 32 */ [16, 15, 31, 33],
    /* 33 */ [34, 16, 32],
    /* 34 */ [35, 17, 16, 33],
    /* 35 */ [36, 18, 17, 34],
    /* 36 */ [19, 18, 35]
]

for (let i = 0; i < size; i++) {
    graph.nodes[i].edges.concat(edges[i].map(j => ary[j]))
}

export default {size, ary, graph}
<commit_msg>sort imports<commit_after>import BorderTile from "./border-tile"
import Graph from "./graph"
import ResourceTile from "./resource-tile"

const size = 37
const ary = []
const graph = new Graph()

// 00-18 are the resource tiles
// 19-36 are the border tiles
for (let i = 0; i < size; i++) {
    const t = i < 19 ? new ResourceTile() : new BorderTile()
    ary.push(t)
    graph.add(t)
}

//
//                21      22      23      24
//
//
//            20      08      09      10      25
//
//
//        19      07      01      02      11      26
//
//
//    36      18      06      00      03      12      27
//
//
//        35      17      05      04      13      28
//
//
//            34      16      15      14      29
//
//
//                33      32      31      30
//
const edges = [
    /* 00 */ [1, 2, 3, 4, 5, 6],
    /* 01 */ [8, 9, 2, 0, 6, 7],
    /* 02 */ [9, 10, 11, 3, 0, 1],
    /* 03 */ [2, 11, 12, 13, 4, 0],
    /* 04 */ [0, 3, 13, 14, 15, 5],
    /* 05 */ [6, 0, 4, 15, 16, 17],
    /* 06 */ [7, 1, 0, 5, 17, 18],
    /* 07 */ [20, 8, 1, 6, 18, 19],
    /* 08 */ [21, 22, 9, 1, 7, 20],
    /* 09 */ [22, 23, 10, 2, 1, 8],
    /* 10 */ [23, 24, 25, 11, 2, 9],
    /* 11 */ [10, 25, 26, 12, 3, 2],
    /* 12 */ [11, 26, 27, 28, 13, 3],
    /* 13 */ [3, 12, 28, 29, 14, 4],
    /* 14 */ [4, 13, 29, 30, 31, 15],
    /* 15 */ [5, 4, 14, 31, 32, 16],
    /* 16 */ [17, 5, 15, 32, 33, 34],
    /* 17 */ [18, 6, 5, 16, 34, 35],
    /* 18 */ [19, 7, 6, 17, 35, 36],
    /* 19 */ [20, 7, 18, 36],
    /* 20 */ [21, 8, 7, 19],
    /* 21 */ [22, 8, 20],
    /* 22 */ [23, 9, 8, 21],
    /* 23 */ [24, 10, 9, 22],
    /* 24 */ [25, 10, 23],
    /* 25 */ [24, 26, 11, 10],
    /* 26 */ [25, 27, 12, 11],
    /* 27 */ [26, 28, 12],
    /* 28 */ [12, 27, 29, 13],
    /* 29 */ [13, 28, 30, 14],
    /* 30 */ [14, 29, 31],
    /* 31 */ [15, 14, 30, 32],
    /* 32 */ [16, 15, 31, 33],
    /* 33 */ [34, 16, 32],
    /* 34 */ [35, 17, 16, 33],
    /* 35 */ [36, 18, 17, 34],
    /* 36 */ [19, 18, 35]
]

for (let i = 0; i < size; i++) {
    graph.nodes[i].edges.concat(edges[i].map(j => ary[j]))
}

export default {size, ary, graph}
<|endoftext|>


<commit_before>// ========================================================================
// SproutCore
// copyright 2006-2008 Sprout Systems, Inc.
// ========================================================================

require('views/view') ;

/**
  @class

  ProgressView displays a progress bar.  It does this mostly through CSS
  classes so that you can style them however you want.  A progress bar must
  have the following structure:

  The outer can form the boundary of the bar while the inner will be adjusted
  to fit the percentage of the progress.

  Style the progress bar with the following CSS classes:

  .progress.indeterminate = to show an indeterminate progress. inner will
      hide.
  .progress.disabled = show as disabled.

  @extends SC.View
*/
SC.ProgressView = SC.View.extend({

  // ........................................
  // PROPERTIES
  //

  /**
    The minimum value of the progress.
  */
  minimum: 0,

  /**
    The maximum value of the progress bar.
  */
  maximum: 1.0,

  // Bind this to the current value of the progress bar.  Note that by default an
  // empty value will disable the progress bar and a multiple value too make it
  // indeterminate.
  value: 0.50,
  valueBindingDefault: SC.Binding.SingleNotEmpty,

  // set to true if the item in progress is indeterminate.  This may be overridden
  // by the actual value.
  isIndeterminate: function(key,value) {
    if (value !== undefined) {
      this._isIndeterminate = value ;
    }
    return this._isIndeterminate && (this.value != SC.Binding.EMPTY_PLACEHOLDER) ;
  }.property(),

  // set to false to disable the progress bar
  isEnabled: function(key, value) {
    if (value !== undefined) {
      this._isEnabled = value ;
    }
    return this._isEnabled && (this.value != SC.Binding.MULTIPLE_PLACEHOLDER) ;
  }.property(),

  _isIndeterminate: false, _isEnabled: true,

  // ........................................
  // STRUCTURE
  //

  emptyElement: '

',

  outlets: ['innerView'],
  innerView: SC.View.outletFor('.inner?'),

  // ........................................
  // INTERNAL SUPPORT
  //

  propertyObserver: function(observing,target,key,value) {
    // collect new settings.
    if (['value','minimum','maximum','isIndeterminate','isEnabled'].include(key)) {
      var isIndeterminate = this.get('isIndeterminate') ;
      var isEnabled = this.get('isEnabled') ;

      Element.setClassName(this,'indeterminate',isIndeterminate) ;
      Element.setClassName(this,'disabled',!isEnabled) ;

      // compute value
      var value ;
      if (isIndeterminate || !isEnabled) {
        value = 0.0 ;
      } else {
        var minimum = this.get('minimum') || 0.0 ;
        var maximum = this.get('maximum') || 1.0 ;
        value = this.get('value') || 0.0 ;
        value = (value - minimum) / (maximum - minimum) ;
        if (value > 1.0) value = 1.0 ;
      }
      value = value * 100 ;
      if (this.innerView) this.innerView.setStyle({ width: (value + '%') }) ;
    }
  }
}) ;

<commit_msg>SC.ProgressView now sets the width of the innerView to 100% when it is set to indeterminate so that it can be styled using the same approach as a determinate progress bar.<commit_after>// ========================================================================
// SproutCore
// copyright 2006-2008 Sprout Systems, Inc.
// ========================================================================

require('views/view') ;

/**
  @class

  ProgressView displays a progress bar.  It does this mostly through CSS
  classes so that you can style them however you want.  A progress bar must
  have the following structure:

  The outer can form the boundary of the bar while the inner will be adjusted
  to fit the percentage of the progress.

  Style the progress bar with the following CSS classes:

  .progress.indeterminate = to show an indeterminate progress. inner will
      be set to fill 100%
  .progress.disabled = show as disabled.

  @extends SC.View
*/
SC.ProgressView = SC.View.extend({

  // ........................................
  // PROPERTIES
  //

  /**
    The minimum value of the progress.
  */
  minimum: 0,

  /**
    The maximum value of the progress bar.
  */
  maximum: 1.0,

  /**
    Bind this to the current value of the progress bar.  Note that by default an
    empty value will disable the progress bar and a multiple value too make it
    indeterminate.
  */
  value: 0.50,
  valueBindingDefault: SC.Binding.SingleNotEmpty,

  /**
    Set to true if the item in progress is indeterminate.  This may be overridden
    by the actual value.
    @returns {Boolean}
  */
  isIndeterminate: function(key,value) {
    if (value !== undefined) {
      this._isIndeterminate = value ;
    }
    return this._isIndeterminate && (this.value != SC.Binding.EMPTY_PLACEHOLDER) ;
  }.property(),

  /**
   Set to false to disable the progress bar.
   @returns {Boolean}
  */
  isEnabled: function(key, value) {
    if (value !== undefined) {
      this._isEnabled = value ;
    }
    return this._isEnabled && (this.value != SC.Binding.MULTIPLE_PLACEHOLDER) ;
  }.property(),

  _isIndeterminate: false, _isEnabled: true,

  // ........................................
  // STRUCTURE
  //

  emptyElement: '

',

  outlets: ['innerView'],
  innerView: SC.View.outletFor('.inner?'),

  // ........................................
  // INTERNAL SUPPORT
  //

  propertyObserver: function(observing,target,key,value) {
    // collect new settings.
    if (['value','minimum','maximum','isIndeterminate','isEnabled'].include(key)) {
      var isIndeterminate = this.get('isIndeterminate') ;
      var isEnabled = this.get('isEnabled') ;

      Element.setClassName(this,'indeterminate',isIndeterminate) ;
      Element.setClassName(this,'disabled',!isEnabled) ;

      // compute value for setting the width of the inner progress
      var value ;
      if (!isEnabled) {
        value = 0.0 ;
      } else if (isIndeterminate) {
        value = 1.0;
      }else {
        var minimum = this.get('minimum') || 0.0 ;
        var maximum = this.get('maximum') || 1.0 ;
        value = this.get('value') || 0.0 ;
        value = (value - minimum) / (maximum - minimum) ;
        if (value > 1.0) value = 1.0 ;
      }
      value = value * 100 ;
      if (this.innerView) this.innerView.setStyle({ width: (value + '%') }) ;
    }
  }
}) ;

<|endoftext|>


<commit_before>import BorderHex from "./border-hex"
import Graph from "./graph"
import ResourceHex from "./resource-hex"

const size = 37
const array = []
const graph = new Graph()

// 00-18 are the resource tiles
// 19-36 are the border tiles
for (let i = 0; i < size; i++) {
    const t = i < 19 ? new ResourceHex() : new BorderHex()
    array.push(t)
    graph.add(t)
}

//
//                21      22      23      24
//
//
//            20      08      09      10      25
//
//
//        19      07      01      02      11      26
//
//
//    36      18      06      00      03      12      27
//
//
//        35      17      05      04      13      28
//
//
//            34      16      15      14      29
//
//
//                33      32      31      30
//
const edges = [
    /* 00 */ [1, 2, 3, 4, 5, 6],
    /* 01 */ [8, 9, 2, 0, 6, 7],
    /* 02 */ [9, 10, 11, 3, 0, 1],
    /* 03 */ [2, 11, 12, 13, 4, 0],
    /* 04 */ [0, 3, 13, 14, 15, 5],
    /* 05 */ [6, 0, 4, 15, 16, 17],
    /* 06 */ [7, 1, 0, 5, 17, 18],
    /* 07 */ [20, 8, 1, 6, 18, 19],
    /* 08 */ [21, 22, 9, 1, 7, 20],
    /* 09 */ [22, 23, 10, 2, 1, 8],
    /* 10 */ [23, 24, 25, 11, 2, 9],
    /* 11 */ [10, 25, 26, 12, 3, 2],
    /* 12 */ [11, 26, 27, 28, 13, 3],
    /* 13 */ [3, 12, 28, 29, 14, 4],
    /* 14 */ [4, 13, 29, 30, 31, 15],
    /* 15 */ [5, 4, 14, 31, 32, 16],
    /* 16 */ [17, 5, 15, 32, 33, 34],
    /* 17 */ [18, 6, 5, 16, 34, 35],
    /* 18 */ [19, 7, 6, 17, 35, 36],
    /* 19 */ [20, 7, 18, 36],
    /* 20 */ [21, 8, 7, 19],
    /* 21 */ [22, 8, 20],
    /* 22 */ [23, 9, 8, 21],
    /* 23 */ [24, 10, 9, 22],
    /* 24 */ [25, 10, 23],
    /* 25 */ [24, 26, 11, 10],
    /* 26 */ [25, 27, 12, 11],
    /* 27 */ [26, 28, 12],
    /* 28 */ [12, 27, 29, 13],
    /* 29 */ [13, 28, 30, 14],
    /* 30 */ [14, 29, 31],
    /* 31 */ [15, 14, 30, 32],
    /* 32 */ [16, 15, 31, 33],
    /* 33 */ [34, 16, 32],
    /* 34 */ [35, 17, 16, 33],
    /* 35 */ [36, 18, 17, 34],
    /* 36 */ [19, 18, 35]
]

for (let i = 0; i < size; i++) {
    graph.nodes[i].edges.push(...edges[i].map(j => array[j]))
}

export default {size, array, graph}
<commit_msg>use some null<commit_after>import BorderHex from "./border-hex"
import Graph from "./graph"
import ResourceHex from "./resource-hex"

const size = 37
const array = []
const graph = new Graph()

// 00-18 are the resource tiles
// 19-36 are the border tiles
for (let i = 0; i < size; i++) {
    const t = i < 19 ? new ResourceHex(null, null) : new BorderHex(null)
    array.push(t)
    graph.add(t)
}

//
//                21      22      23      24
//
//
//            20      08      09      10      25
//
//
//        19      07      01      02      11      26
//
//
//    36      18      06      00      03      12      27
//
//
//        35      17      05      04      13      28
//
//
//            34      16      15      14      29
//
//
//                33      32      31      30
//
const edges = [
    /* 00 */ [1, 2, 3, 4, 5, 6],
    /* 01 */ [8, 9, 2, 0, 6, 7],
    /* 02 */ [9, 10, 11, 3, 0, 1],
    /* 03 */ [2, 11, 12, 13, 4, 0],
    /* 04 */ [0, 3, 13, 14, 15, 5],
    /* 05 */ [6, 0, 4, 15, 16, 17],
    /* 06 */ [7, 1, 0, 5, 17, 18],
    /* 07 */ [20, 8, 1, 6, 18, 19],
    /* 08 */ [21, 22, 9, 1, 7, 20],
    /* 09 */ [22, 23, 10, 2, 1, 8],
    /* 10 */ [23, 24, 25, 11, 2, 9],
    /* 11 */ [10, 25, 26, 12, 3, 2],
    /* 12 */ [11, 26, 27, 28, 13, 3],
    /* 13 */ [3, 12, 28, 29, 14, 4],
    /* 14 */ [4, 13, 29, 30, 31, 15],
    /* 15 */ [5, 4, 14, 31, 32, 16],
    /* 16 */ [17, 5, 15, 32, 33, 34],
    /* 17 */ [18, 6, 5, 16, 34, 35],
    /* 18 */ [19, 7, 6, 17, 35, 36],
    /* 19 */ [20, 7, 18, 36],
    /* 20 */ [21, 8, 7, 19],
    /* 21 */ [22, 8, 20],
    /* 22 */ [23, 9, 8, 21],
    /* 23 */ [24, 10, 9, 22],
    /* 24 */ [25, 10, 23],
    /* 25 */ [24, 26, 11, 10],
    /* 26 */ [25, 27, 12, 11],
    /* 27 */ [26, 28, 12],
    /* 28 */ [12, 27, 29, 13],
    /* 29 */ [13, 28, 30, 14],
    /* 30 */ [14, 29, 31],
    /* 31 */ [15, 14, 30, 32],
    /* 32 */ [16, 15, 31, 33],
    /* 33 */ [34, 16, 32],
    /* 34 */ [35, 17, 16, 33],
    /* 35 */ [36, 18, 17, 34],
    /* 36 */ [19, 18, 35]
]

for (let i = 0; i < size; i++) {
    graph.nodes[i].edges.push(...edges[i].map(j => array[j]))
}

export default {size, array, graph}
<|endoftext|>


<commit_before>(function ($) {
    $.fn.disable = function (action) {
        var text = $(this).html();
        if (action) {
            if (text.substr(text.length - 1) == "r")
                text = text.substr(0, text.length - 1) + "ndo";
            text += "...";
        }
        else {
            if (text.substr(text.length - 3) == "...")
                text = text.substr(0, text.length - 3);
            if (text.substr(text.length - 3) == "ndo")
                text = text.substr(0, text.length - 3) + "r";
        }
        $(this).html(text);
        $(this).attr("disabled", action);
    };

    $.fn.toggleDisable = function () {
        $(this).disable(!$(this).is(":disabled"));
    };
}(jQuery));<commit_msg>Trying to use ellipsis instead of three periods.<commit_after>(function ($) {
    $.fn.disable = function (action) {
        var text = $(this).html();
        if (action) {
            if (text.substr(text.length - 1) == "r")
                text = text.substr(0, text.length - 1) + "ndo";
            text += "…";
        }
        else {
            if (text.substr(text.length - 1) == "…")
                text = text.substr(0, text.length - 1);
            if (text.substr(text.length - 3) == "ndo")
                text = text.substr(0, text.length - 3) + "r";
        }
        $(this).html(text);
        $(this).attr("disabled", action);
    };

    $.fn.toggleDisable = function () {
        $(this).disable(!$(this).is(":disabled"));
    };
}(jQuery));
<|endoftext|>