<commit_before>/*
 * library dependencies:
 *      jquery 1.8.3
 *      fos-routing
 *      fileUploader
 *      colorBox
 * external dependencies:
 *      appLocale
 */

// fansWorld file upload plugin 1.0

// the semi-colon before function invocation is a safety net against concatenated
// scripts and/or other plugins which may not be closed properly.
//;(function ($, window, document, undefined) {
$(document).ready(function () {

    "use strict";

    // undefined is used here as the undefined global variable in ECMAScript 3 is
    // mutable (ie. it can be changed by someone else). undefined isn't really being
    // passed in so we can ensure the value of it is truly undefined. In ES5, undefined
    // can no longer be modified.

    // window and document are passed through as local variable rather than global
    // as this (slightly) quickens the resolution process and can be more efficiently
    // minified (especially when both are regularly referenced in your plugin).

    // Create the defaults once
    var pluginName = "fwUploader";
    var defaults = {
        propertyName: "fansworld",
        uploadtoken: null,
        mediaExtensions: {
            photo: ['jpg', 'jpeg', 'png', 'gif'],                       // Allowed extensions by media type
            video: ['avi', 'mov', 'mpeg'],
            audio: ['wav', 'mp3', 'ogg', 'midi']
        },
        action: {
            photo: Routing.generate(appLocale + '_photo_fileupload'),   // link for photos
            video: 'http://www.kaltura.com/api_v3/index.php'            // link for videos
        },
        mediaType: null,
        // custom bindings
        onSubmit: function(id, fileName){},
        onComplete: function(id, fileName, responseJSON){},
        onCancel: function(id, fileName){},
        onUpload: function(id, fileName, xhr){},
        onProgress: function(id, fileName, loaded, total){},
        onError: function(id, fileName, reason) {}
    };

    // The actual plugin constructor
    function Plugin(element, options) {
        this.element = element;
        // jQuery has an extend method which merges the contents of two or
        // more objects, storing the result in the first object. The first object
        // is generally empty as we don't want to alter the default options for
        // future instances of the plugin
        this.options = $.extend({}, defaults, options);
        this._defaults = defaults;
        this._name = pluginName;
        this.init();
    }

    Plugin.prototype = {
        init: function () {
            var that = this;
            $(that.element).addClass(that._name);
            that.options.mediaType = $(that.element).attr('data-upload');
            $(that.element).bind("destroyed", $.proxy(that.teardown, that));
            $(that.element).colorbox({
                innerWidth: 700,
                innerHeight: 475,
                onComplete: function() {
                    if(that.options.mediaType === 'video')
                    {
                        // Get kaltura token before popup opens
                        that.getToken('fileName', function(uploadToken) {
                            console.log("token: " + uploadToken)
                            that.createFwGenericUploader();
                            that.uploader.setParams({uploadTokenId: that.options.uploadtoken});
                        });
                    } else {
                        that.createFwUploader();
                    }
                    that.resizePopup();
                }
            });
        },
        bindAlbumActions: function() {
            var that = this;
            if ($('#form_album').val() === 'NEW') {
                that.spawnNewAlbumField($('#form_album'));
            }
            $('#form_album').change(function(e){
                var el = $(this);
                if (el.val() === 'NEW') {
                    that.spawnNewAlbumField(el);
                } else {
                    $('#form_album_new_name').parents('.control-group').remove();
                }
            });
        },
        spawnNewAlbumField: function(el) {
            var that = this;
            var newfield = $(".templateFieldAlbumName .control-group").clone();
            newfield.find('input').attr('id', 'form_album_new_name');
            el.parents('.control-group').after(newfield);
            $('#form_album_new_name').parents('.control-group').slideDown('fast', function() {
                that.resizePopup();
            });
        },
        bindFormSubmit: function() {
            var that = this;
            console.log("bindFormSubmit")
            //$('#cboxLoadedContent').find("form") <--- suck it from above
            $("form.upload-" + that.options.mediaType).submit(function() {
                console.log("before submit")
                var data = $(this).serializeArray();
                var href = $(this).attr('action');
                $.colorbox({
                    href: href ,
                    data: data,
                    onComplete: function(){
                        that.bindFormActions();
                        that.resizePopup();
                    }
                });
                return false;
            });
        },
        bindFormActions: function() {
            var that = this;
            that.bindFormSubmit();
            that.bindAlbumActions();
            setTimeout(function(){ that.resizePopup(); }, 2000);
        },
        createFwUploader: function() {
            var that = this;
            var uploader = new qq.FileUploader({
                element: $("#file-uploader")[0],
                action: that.options.action[that.options.mediaType],
                debug: true,
                multiple: false,
                maxConnections: 1,
                allowedExtensions: that.options.mediaExtensions[that.options.mediaType],
                onComplete: function(id, fileName, responseJSON) {
                    if(responseJSON.success) {
                        $.colorbox({
                            href: Routing.generate(appLocale + '_photo_filemeta', {
                                'originalFile': responseJSON.originalFile,
                                'tempFile':responseJSON.tempFile,
                                'width': responseJSON.width,
                                'height': responseJSON.height
                            }),
                            iframe: false,
                            innerWidth: 700,
                            innerHeight: 700,
                            onComplete: function() {
                                that.resizePopup();
                                that.bindFormActions();
                            }
                        });
                    }
                    return that.options.onComplete(id, fileName, responseJSON);
                },
                onUpload: function() {
                    console.log("onUpload");
                    that.resizePopup();
                },
                onProgress: function(id, fileName, loaded, total) {
                    if (loaded !== total){
                        $( "#progressbar .bar" ).css('width', Math.round(loaded / total * 100)+'%');
                    } else {
                        $( "#progressbar .bar" ).css('width','100%');
                    }
                    that.resizePopup();
                },
                onSubmit: function(id, fileName){
                    return that.options.onSubmit(id, fileName);
                }
            });
        },
        createFwVideoUploader: function() {
            var that = this;
            that.uploader = new qq.FileUploader({
                element: $('#file-uploader')[0],
                action: that.options.action[that.options.mediaType],
                multiple: false,
                forceMultipart: true,
                normalHeaders: false,
                responsePassthrough: true,
                debug: true,
                failedUploadTextDisplay: {mode: 'none'},
                onSubmit: function(file, ext){
                    that.uploader.setParams({
                        inputName: 'resource:fileData',
                        service: 'media',
                        action: 'addContent',
                        entryId: $('#entryid').val(),
                        ks: 'MjkyOTNmOGEyZmY1MzJmODA0MDZhMmY2OTdhZGMyODAzNTRmNjhjMnwxMTY0ODMyOzExNjQ4MzI7MTM1ODAxMTY2MDsyOzI1NTI7RmFuc3dvcmxkQWRtaW47',
                        'resource:objectType': 'KalturaUploadedFileResource'
                    });
                    return that.options.onSubmit(id, fileName);
                },
                // kaltura returns XML
                onComplete: function(id, fileName, xml){
                    var xmlDoc = $.parseXML(xml);
                    var $xml = $( xmlDoc );
                    //var result = $xml.find( "result" );
                    return that.options.onComplete(id, fileName, xml);
                },
                onUpload: function(id, fileName, xhr) {
                    that.resizePopup();
                    return that.options.onUpload(id, fileName, xhr);
                },
                onProgress: function(id, fileName, loaded, total) {
                    return that.options.onProgress(id, fileName, loaded, total);
                }
            });
        },
        createFwGenericUploader: function() {
            var that = this;
            that.uploader = new qq.FileUploader({
                element: $('#file-uploader')[0],
                action: that.options.action[that.options.mediaType],
                multiple: false,
                forceMultipart: true,
                normalHeaders: false,
                responsePassthrough: true,
                debug: true,
                failedUploadTextDisplay: {mode: 'none'},
                onSubmit: function(id, fileName){
                    that.uploader.setParams({
                        inputName: 'resource:fileData',
                        service: 'media',
                        action: 'addContent',
                        entryId: $('#entryid').val(),
                        ks: 'MjkyOTNmOGEyZmY1MzJmODA0MDZhMmY2OTdhZGMyODAzNTRmNjhjMnwxMTY0ODMyOzExNjQ4MzI7MTM1ODAxMTY2MDsyOzI1NTI7RmFuc3dvcmxkQWRtaW47',
                        'resource:objectType': 'KalturaUploadedFileResource'
                    });
                    that.options.onSubmit(id, fileName);
                },
                onComplete: function(id, fileName, responseJSON) {
                    return that.options.onComplete(id, fileName, responseJSON);
                },
                onUpload: function(id, fileName, xhr) {
                    that.resizePopup();
                    return that.options.onUpload(id, fileName, xhr);
                },
                onProgress: function(id, fileName, loaded, total) {
                    return that.options.onProgress(id, fileName, loaded, total);
                },
            });
        },
        getToken: function(filename, callback) {
            var that = this;
            $.ajax({
                url: 'http://www.kaltura.com/api_v3/index.php',
                data: {
                    service: 'uploadToken',
                    action: 'add',
                    ks: 'MjkyOTNmOGEyZmY1MzJmODA0MDZhMmY2OTdhZGMyODAzNTRmNjhjMnwxMTY0ODMyOzExNjQ4MzI7MTM1ODAxMTY2MDsyOzI1NTI7RmFuc3dvcmxkQWRtaW47',
                    'uploadToken:fileName': filename,
                    'uploadToken:objectType': 'KalturaUploadToken'
                },
                dataType: 'xml',
                success: function(r) {
                    that.options.uploadtoken = $(r).find('id').text();
                    callback(that.options.uploadtoken);
                }
            });
        },
        resizePopup: function() {
            window.top.resizeColorbox({innerHeight: $('.popup-content').height() });
        },
        destroy: function() {
            var that = this;
            $(that.element).unbind("destroyed", that.teardown);
            that.teardown();
        },
        teardown: function() {
            var that = this;
            $.removeData($(that.element)[0], that._name);
            $(that.element).removeClass(that._name);
            $(that.element).removeClass('cboxElement').removeData('colorbox');
            that.unbind();
            //$.colorbox.remove();
            that.element = null;
        },
        bind: function() {  },
        unbind: function() {  }
    };

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[pluginName] = function (options) {
        return this.each(function () {
            if (!$.data(this, pluginName)) {
                $.data(this, pluginName, new Plugin(this, options));
            }
        });
    };

});<commit_msg>update fw.ui.uploader.js 1.1 (resize only after content has finished loading)<commit_after>/*
 * library dependencies:
 *      jquery 1.8.3
 *      fos-routing
 *      fileUploader
 *      colorBox
 * external dependencies:
 *      appLocale
 */

// fansWorld file upload plugin 1.1

// the semi-colon before function invocation is a safety net against concatenated
// scripts and/or other plugins which may not be closed properly.
//;(function ($, window, document, undefined) {
$(document).ready(function () {

    "use strict";

    // undefined is used here as the undefined global variable in ECMAScript 3 is
    // mutable (ie. it can be changed by someone else). undefined isn't really being
    // passed in so we can ensure the value of it is truly undefined. In ES5, undefined
    // can no longer be modified.

    // window and document are passed through as local variable rather than global
    // as this (slightly) quickens the resolution process and can be more efficiently
    // minified (especially when both are regularly referenced in your plugin).

    // Create the defaults once
    var pluginName = "fwUploader";
    var defaults = {
        propertyName: "fansworld",
        uploadtoken: null,
        mediaExtensions: {
            photo: ['jpg', 'jpeg', 'png', 'gif'],                       // Allowed extensions by media type
            video: ['avi', 'mov', 'mpeg'],
            audio: ['wav', 'mp3', 'ogg', 'midi']
        },
        action: {
            photo: Routing.generate(appLocale + '_photo_fileupload'),   // link for photos
            video: 'http://www.kaltura.com/api_v3/index.php'            // link for videos
        },
        mediaType: null,
        // custom bindings
        onSubmit: function(id, fileName){},
        onComplete: function(id, fileName, responseJSON){},
        onCancel: function(id, fileName){},
        onUpload: function(id, fileName, xhr){},
        onProgress: function(id, fileName, loaded, total){},
        onError: function(id, fileName, reason) {}
    };

    // The actual plugin constructor
    function Plugin(element, options) {
        this.element = element;
        // jQuery has an extend method which merges the contents of two or
        // more objects, storing the result in the first object. The first object
        // is generally empty as we don't want to alter the default options for
        // future instances of the plugin
        this.options = $.extend({}, defaults, options);
        this._defaults = defaults;
        this._name = pluginName;
        this.init();
    }

    Plugin.prototype = {
        init: function () {
            var that = this;
            $(that.element).addClass(that._name);
            that.options.mediaType = $(that.element).attr('data-upload');
            $(that.element).bind("destroyed", $.proxy(that.teardown, that));
            $(that.element).colorbox({
                innerWidth: 700,
                innerHeight: 475,
                onComplete: function() {
                    if(that.options.mediaType === 'video')
                    {
                        // Get kaltura token before popup opens
                        that.getToken('fileName', function(uploadToken) {
                            console.log("token: " + uploadToken)
                            that.createFwGenericUploader();
                            that.uploader.setParams({uploadTokenId: that.options.uploadtoken});
                            that.resizePopup(); // fire this event only when content has loaded
                        });
                    } else {
                        that.createFwUploader();
                        that.resizePopup();
                    }
                }
            });
        },
        bindAlbumActions: function() {
            var that = this;
            if ($('#form_album').val() === 'NEW') {
                that.spawnNewAlbumField($('#form_album'));
            }
            $('#form_album').change(function(e){
                var el = $(this);
                if (el.val() === 'NEW') {
                    that.spawnNewAlbumField(el);
                } else {
                    $('#form_album_new_name').parents('.control-group').remove();
                }
            });
        },
        spawnNewAlbumField: function(el) {
            var that = this;
            var newfield = $(".templateFieldAlbumName .control-group").clone();
            newfield.find('input').attr('id', 'form_album_new_name');
            el.parents('.control-group').after(newfield);
            $('#form_album_new_name').parents('.control-group').slideDown('fast', function() {
                that.resizePopup();
            });
        },
        bindFormSubmit: function() {
            var that = this;
            console.log("bindFormSubmit")
            //$('#cboxLoadedContent').find("form") <--- suck it from above
            $("form.upload-" + that.options.mediaType).submit(function() {
                console.log("before submit")
                var data = $(this).serializeArray();
                var href = $(this).attr('action');
                $.colorbox({
                    href: href ,
                    data: data,
                    onComplete: function(){
                        that.bindFormActions();
                        that.resizePopup();
                    }
                });
                return false;
            });
        },
        bindFormActions: function() {
            var that = this;
            that.bindFormSubmit();
            that.bindAlbumActions();
            setTimeout(function(){ that.resizePopup(); }, 2000);
        },
        createFwUploader: function() {
            var that = this;
            var uploader = new qq.FileUploader({
                element: $("#file-uploader")[0],
                action: that.options.action[that.options.mediaType],
                debug: true,
                multiple: false,
                maxConnections: 1,
                allowedExtensions: that.options.mediaExtensions[that.options.mediaType],
                onComplete: function(id, fileName, responseJSON) {
                    if(responseJSON.success) {
                        $.colorbox({
                            href: Routing.generate(appLocale + '_photo_filemeta', {
                                'originalFile': responseJSON.originalFile,
                                'tempFile':responseJSON.tempFile,
                                'width': responseJSON.width,
                                'height': responseJSON.height
                            }),
                            iframe: false,
                            innerWidth: 700,
                            innerHeight: 700,
                            onComplete: function() {
                                that.resizePopup();
                                that.bindFormActions();
                            }
                        });
                    }
                    return that.options.onComplete(id, fileName, responseJSON);
                },
                onUpload: function() {
                    console.log("onUpload");
                    that.resizePopup();
                },
                onProgress: function(id, fileName, loaded, total) {
                    if (loaded !== total){
                        $( "#progressbar .bar" ).css('width', Math.round(loaded / total * 100)+'%');
                    } else {
                        $( "#progressbar .bar" ).css('width','100%');
                    }
                    that.resizePopup();
                },
                onSubmit: function(id, fileName){
                    return that.options.onSubmit(id, fileName);
                }
            });
        },
        createFwVideoUploader: function() {
            var that = this;
            that.uploader = new qq.FileUploader({
                element: $('#file-uploader')[0],
                action: that.options.action[that.options.mediaType],
                multiple: false,
                forceMultipart: true,
                normalHeaders: false,
                responsePassthrough: true,
                debug: true,
                failedUploadTextDisplay: {mode: 'none'},
                onSubmit: function(file, ext){
                    that.uploader.setParams({
                        inputName: 'resource:fileData',
                        service: 'media',
                        action: 'addContent',
                        entryId: $('#entryid').val(),
                        ks: 'MjkyOTNmOGEyZmY1MzJmODA0MDZhMmY2OTdhZGMyODAzNTRmNjhjMnwxMTY0ODMyOzExNjQ4MzI7MTM1ODAxMTY2MDsyOzI1NTI7RmFuc3dvcmxkQWRtaW47',
                        'resource:objectType': 'KalturaUploadedFileResource'
                    });
                    return that.options.onSubmit(id, fileName);
                },
                // kaltura returns XML
                onComplete: function(id, fileName, xml){
                    var xmlDoc = $.parseXML(xml);
                    var $xml = $( xmlDoc );
                    //var result = $xml.find( "result" );
                    return that.options.onComplete(id, fileName, xml);
                },
                onUpload: function(id, fileName, xhr) {
                    that.resizePopup();
                    return that.options.onUpload(id, fileName, xhr);
                },
                onProgress: function(id, fileName, loaded, total) {
                    return that.options.onProgress(id, fileName, loaded, total);
                }
            });
        },
        createFwGenericUploader: function() {
            var that = this;
            that.uploader = new qq.FileUploader({
                element: $('#file-uploader')[0],
                action: that.options.action[that.options.mediaType],
                multiple: false,
                forceMultipart: true,
                normalHeaders: false,
                responsePassthrough: true,
                debug: true,
                failedUploadTextDisplay: {mode: 'none'},
                onSubmit: function(id, fileName){
                    that.uploader.setParams({
                        inputName: 'resource:fileData',
                        service: 'media',
                        action: 'addContent',
                        entryId: $('#entryid').val(),
                        ks: 'MjkyOTNmOGEyZmY1MzJmODA0MDZhMmY2OTdhZGMyODAzNTRmNjhjMnwxMTY0ODMyOzExNjQ4MzI7MTM1ODAxMTY2MDsyOzI1NTI7RmFuc3dvcmxkQWRtaW47',
                        'resource:objectType': 'KalturaUploadedFileResource'
                    });
                    that.options.onSubmit(id, fileName);
                },
                onComplete: function(id, fileName, responseJSON) {
                    return that.options.onComplete(id, fileName, responseJSON);
                },
                onUpload: function(id, fileName, xhr) {
                    that.resizePopup();
                    return that.options.onUpload(id, fileName, xhr);
                },
                onProgress: function(id, fileName, loaded, total) {
                    return that.options.onProgress(id, fileName, loaded, total);
                },
            });
        },
        getToken: function(filename, callback) {
            var that = this;
            $.ajax({
                url: 'http://www.kaltura.com/api_v3/index.php',
                data: {
                    service: 'uploadToken',
                    action: 'add',
                    ks: 'MjkyOTNmOGEyZmY1MzJmODA0MDZhMmY2OTdhZGMyODAzNTRmNjhjMnwxMTY0ODMyOzExNjQ4MzI7MTM1ODAxMTY2MDsyOzI1NTI7RmFuc3dvcmxkQWRtaW47',
                    'uploadToken:fileName': filename,
                    'uploadToken:objectType': 'KalturaUploadToken'
                },
                dataType: 'xml',
                success: function(r) {
                    that.options.uploadtoken = $(r).find('id').text();
                    callback(that.options.uploadtoken);
                }
            });
        },
        resizePopup: function() {
            window.top.resizeColorbox({innerHeight: $('.popup-content').height() });
        },
        destroy: function() {
            var that = this;
            $(that.element).unbind("destroyed", that.teardown);
            that.teardown();
        },
        teardown: function() {
            var that = this;
            $.removeData($(that.element)[0], that._name);
            $(that.element).removeClass(that._name);
            $(that.element).removeClass('cboxElement').removeData('colorbox');
            that.unbind();
            //$.colorbox.remove();
            that.element = null;
        },
        bind: function() {  },
        unbind: function() {  }
    };

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[pluginName] = function (options) {
        return this.each(function () {
            if (!$.data(this, pluginName)) {
                $.data(this, pluginName, new Plugin(this, options));
            }
        });
    };

});<|endoftext|>


<commit_before>app.service('AppService', [
  '$rootScope',
  '$mdDialog',
  '$log',
  '$location',
  '$timeout',
  'fb',
  function($rootScope, $mdDialog, $log, $location, $timeout, fb){

    // @var object config The default app config
    this.config = {
      note: undefined,
      notes: [],
      updated: Date.now()
    };

    this.reset = function(){
      this.title = 'Notes';
      this.auth = 0;
      this.reloading = 0;
      this.timeout = undefined;
      this.snapshot = undefined;
      this.userRef = undefined;
      this.accountRef = undefined;
      this.userRef = undefined;
      this.stateRef = undefined;
      this.note = undefined;
      this.notes = [];
      this.account = {};
    };

    this.logout = function(){
      this.reset();
      $rootScope.$emit('load', this.notes, this.note);
      fb.unauth();
    };

    /**
     * Creates a key by converting a uid to md5
     *
     * @return string The md5 key
     */
    this.key = function(){
      return CryptoJS.MD5(this.auth.uid).toString();
    };

    /**
     * Encrypts a string
     *
     * @param string str The string
     * @return string The encrypted string
     */
    this.encrypt = function(str){
      return CryptoJS.AES.encrypt(str, this.key()).toString();
    };

    /**
     * Decrypts a string
     *
     * @param string str The string
     * @return string The decrypted string
     */
    this.decrypt = function(str){
      return CryptoJS.AES.decrypt(str, this.key()).toString(CryptoJS.enc.Utf8);
    };

    /**
     * Handle Firebase snapshot events
     *
     * @param object snapshot The Firebase snapshot
     * @param string action The event action
     */
    this.handle = function(snapshot, action){
      this.snapshot = snapshot;

      $log.info('Firebase '+action+': '+snapshot.key());

      // Initial state load
      if(action === 'added'){
        if(snapshot.key() === 'state'){
          this.setState(snapshot.val());
        }else if(snapshot.key() === 'account'){
          this.account = snapshot.val();
        }
      }

      if(0 && !this.reloading){
        clearTimeout(this.timeout);

        this.timeout = setTimeout(function(){
          $scope = angular.element(document.getElementById('content')).scope();
          $scope.$apply(function(){
            $scope.reload();
          });
        }, 1000);
      }
    };

    // SETTERS & GETTERS ------------------------------------

    this.setAuth = function(auth){
      $log.log('setAuth');

      var $app = this;

      $app.reset();

      $app.auth = auth;

      $app.userRef = fb.child($app.key());

      // Firebase Events
      $app.userRef.on('child_added', function(snapshot){
        $app.handle(snapshot, 'added');
      });

      $app.userRef.on('child_changed', function(snapshot){
        $app.handle(snapshot, 'changed');
      });

      $app.userRef.on('child_removed', function(snapshot){
        $app.handle(snapshot, 'removed');
      });

      $app.userRef.on('child_moved', function(snapshot){
        $app.handle(snapshot, 'moved');
      });

      $app.stateRef = $app.userRef.child('state'),
      $app.accountRef = $app.userRef.child('account');

      // Initial signups
      if(/^\/signup\/?/.test($location.path())){
        $app.signup();
      }else if(/^\/login\/?/.test($location.path())){
        $location.path('/');
      }
    }

    this.getAuth = function(){
      return this.auth;
    }

    this.setTitle = function(title){
      this.title = title;
      $mdDialog.hide();
    };

    this.getTitle = function(){
      return this.title;
    };

    /**
     * Sets the current state
     */
    this.setState = function(str){
        $log.log('setState');

        var $app = this;

        if(str){
          str = this.decrypt(str);

          if(/^\{/.test(str)){
            state = JSON.parse(str);

            $app.note = {};
            $app.notes = state.notes;

            // Set the instance of note from notes
            for(var i=0; i<$app.notes.length; i++){
              var note = $app.notes[i];
              if(note.id == state.note.id){
                $app.note = note;
              }
            }

            $timeout(function(){
              $log.log('Emit: load');
              $rootScope.$emit('load', $app.notes, $app.note);
            }, 100);
          }
        }
    };

    /**
     * Gets the account name by concat first and last name
     *
     * @return string The account name
     */
    this.getName = function(){
      return (this.account && this.account.first_name) ? this.account.first_name + ' ' + this.account.last_name : '';
    }

    // APP LOGIC ------------------------------------

    /**
     * Completes signup
     */
    this.signup = function(){
      $scope = angular.element(document.getElementById('content')).scope();

      this.account = {
        first_name: $scope.first_name,
        last_name: $scope.last_name,
        email: $scope.email
      };

      var state = {
          note: this.note,
          notes: this.notes,
          updated: Date.now()
        },
        str = JSON.stringify(state);

      // Firebase
      str = this.encrypt(str);

      this.userRef.set({
        account: this.account,
        state: str
      }, function(){
        $location.path('/');
      });
    };

    /**
     * Updates a note
     */
    this.update = function(){

      $log.log(this.note);

      var note = this.note,
          id = note.id || 0,
          now = Date.now();

      // ADD NOTE
      if(!id){
        id = (this.notes.length) ? _.max(this.notes, function(note){ return note.id; }).id++ : 1;

        note.id = id;
        note.created = now;
        note.updated = now;
        this.notes.unshift(note);
        this.show(note);

        $log.log('ADD NOTE...');
      // UPDATE NOTE
      }else{
        this.note.updated = now;

        $log.log('UPDATE NOTE...');
      }

      this.updated = now;
      this.save();
    };

    /**
     * Gets a note
     *
     * @param integer [id] The note id
     * @return object The note object
     */
    this.get = function(id){
      id = id || this.id;
      return _.findWhere(this.notes, {id: id});
    };

    /**
     * Adds a note
     */
    this.add = function(){
      this.note = {};
      this.save();
      $rootScope.$emit('load', this.notes, this.note);
    };

    /**
     * Removes a note
     *
     * @param integer|object [id=this.note] The note id or object
     */
    this.remove = function(id){
      if(typeof id === 'object' && id.id){
        id = id.id;
      }

      var note = (typeof id === 'number') ? _.findWhere(this.notes, {id: id}) : this.note;

      if(note){
          var $app = this;

          $mdDialog.show({
            templateUrl: 'views/dialogs/confirm.html',
            locals: {
              params: {
                title: 'Delete Note?',
                message: '
You are about to delete the note named...

'+note.name+'
',
                onOk: function(){
                  $app.notes = _.without($app.notes, note);
                  $app.note = undefined;
                  $app.save();
                  $rootScope.$emit('load', $app.notes, $app.note);
                },
                onCancel: function(){}
              }
            },
            parent: 'body',
            controller: ConfirmDialog
          });
      }
    };

    /**
     * Shows a note
     *
     * @param object note The note
     */
    this.show = function(note){
      $log.log(note);

      var $app = this;
      this.note = note;
      //this.save();

      // Timeout used here because the main view needs time to load
      $timeout(function(){
        $rootScope.$emit('load', $app.notes, $app.note);
      }, 100);
    };

    /**
     * Saves the application state
     */
    this.save = function(){
      var state = {};

      // Build runtime state
      for(var prop in this.config){
        state[prop] = this[prop];
      }

      var str = JSON.stringify(state);

      // Firebase
      str = this.encrypt(str);
      this.stateRef.set(str);
      this.accountRef.set(this.account);
    };

    /**
     * Prompt to reload Firebase state
     */
    this.reload = function(){
      // Reload Firebase state
      if(this.snapshot && !this.reloading){
        this.reloading = true;
        var state, str = this.snapshot.val();

        str = this.decrypt(str);

        if(/^\{/.test(str)){
          state = JSON.parse(str);

          if(state.updated > this.updated){

            var $modal = $('#modal-confirm');
            $('.modal-title', $modal).text('Reload?');
            $('.modal-body', $modal).html('
A note was updated & saved remotely.
\
            Do you want to reload your local notes?
');

            $modal.off('hidden.bs.modal').on('hidden.bs.modal', function(e){
              $app.reloading = false;
            });

            $('.btn-yes', $modal).off('click').on('click', function(e){
              $modal.modal('hide');

              str = $app.snapshot.val();

              str = $app.decrypt(str);

              state = JSON.parse(str);

              // Fixes note hash keys
              for(var i=0; i<state.notes.length; i++){
                delete state.notes[i]['$$hashKey'];
              }

              this.notes = state.notes;

              // Fix note reference
              if(this.note && this.note.id){
                this.note = $scope.get(this.note.id);
              }

              this.$apply();

              $app.reloading = false;
            });

            $('.btn-no', $modal).off('click').on('click', function(e){
              $app.reloading = false;
            });

            $modal.modal();
          }else{
            $app.reloading = false;
          }
        }else{
          $app.reloading = false;
        }
      }
    };

    var $app = this;

    // Initial Page Load Authorization
    fb.onAuth(function(auth){
      if(auth){
        $log.info('Logged In');
        $app.setAuth(auth);
      }else{
        $log.warn('Logged Out!');
        if(!/^\/signup\/?/.test($location.path())){
          $location.path('/login');
        }
      }
    });
  }
]);
<commit_msg>Clean up some debugging console output<commit_after>app.service('AppService', [
  '$rootScope',
  '$mdDialog',
  '$log',
  '$location',
  '$timeout',
  'fb',
  function($rootScope, $mdDialog, $log, $location, $timeout, fb){

    // @var object config The default app config
    this.config = {
      note: undefined,
      notes: [],
      updated: Date.now()
    };

    this.reset = function(){
      this.title = 'Notes';
      this.auth = 0;
      this.reloading = 0;
      this.timeout = undefined;
      this.snapshot = undefined;
      this.userRef = undefined;
      this.accountRef = undefined;
      this.userRef = undefined;
      this.stateRef = undefined;
      this.note = undefined;
      this.notes = [];
      this.account = {};
    };

    this.logout = function(){
      this.reset();
      $rootScope.$emit('load', this.notes, this.note);
      fb.unauth();
    };

    /**
     * Creates a key by converting a uid to md5
     *
     * @return string The md5 key
     */
    this.key = function(){
      return CryptoJS.MD5(this.auth.uid).toString();
    };

    /**
     * Encrypts a string
     *
     * @param string str The string
     * @return string The encrypted string
     */
    this.encrypt = function(str){
      return CryptoJS.AES.encrypt(str, this.key()).toString();
    };

    /**
     * Decrypts a string
     *
     * @param string str The string
     * @return string The decrypted string
     */
    this.decrypt = function(str){
      return CryptoJS.AES.decrypt(str, this.key()).toString(CryptoJS.enc.Utf8);
    };

    /**
     * Handle Firebase snapshot events
     *
     * @param object snapshot The Firebase snapshot
     * @param string action The event action
     */
    this.handle = function(snapshot, action){
      this.snapshot = snapshot;

      $log.info('Firebase '+action+': '+snapshot.key());

      // Initial state load
      if(action === 'added'){
        if(snapshot.key() === 'state'){
          this.setState(snapshot.val());
        }else if(snapshot.key() === 'account'){
          this.account = snapshot.val();
        }
      }

      if(0 && !this.reloading){
        clearTimeout(this.timeout);

        this.timeout = setTimeout(function(){
          $scope = angular.element(document.getElementById('content')).scope();
          $scope.$apply(function(){
            $scope.reload();
          });
        }, 1000);
      }
    };

    // SETTERS & GETTERS ------------------------------------

    this.setAuth = function(auth){
      $log.log('setAuth');

      var $app = this;

      $app.reset();

      $app.auth = auth;

      $app.userRef = fb.child($app.key());

      // Firebase Events
      $app.userRef.on('child_added', function(snapshot){
        $app.handle(snapshot, 'added');
      });

      $app.userRef.on('child_changed', function(snapshot){
        $app.handle(snapshot, 'changed');
      });

      $app.userRef.on('child_removed', function(snapshot){
        $app.handle(snapshot, 'removed');
      });

      $app.userRef.on('child_moved', function(snapshot){
        $app.handle(snapshot, 'moved');
      });

      $app.stateRef = $app.userRef.child('state'),
      $app.accountRef = $app.userRef.child('account');

      // Initial signups
      if(/^\/signup\/?/.test($location.path())){
        $app.signup();
      }else if(/^\/login\/?/.test($location.path())){
        $location.path('/');
      }
    }

    this.getAuth = function(){
      return this.auth;
    }

    this.setTitle = function(title){
      this.title = title;
      $mdDialog.hide();
    };

    this.getTitle = function(){
      return this.title;
    };

    /**
     * Sets the current state
     */
    this.setState = function(str){
        $log.log('setState');

        var $app = this;

        if(str){
          str = this.decrypt(str);

          if(/^\{/.test(str)){
            state = JSON.parse(str);

            $app.note = {};
            $app.notes = state.notes;

            // Set the instance of note from notes
            for(var i=0; i<$app.notes.length; i++){
              var note = $app.notes[i];
              if(note.id == state.note.id){
                $app.note = note;
              }
            }

            $timeout(function(){
              $log.log('Emit: load');
              $rootScope.$emit('load', $app.notes, $app.note);
            }, 100);
          }
        }
    };

    /**
     * Gets the account name by concat first and last name
     *
     * @return string The account name
     */
    this.getName = function(){
      return (this.account && this.account.first_name) ? this.account.first_name + ' ' + this.account.last_name : '';
    }

    // APP LOGIC ------------------------------------

    /**
     * Completes signup
     */
    this.signup = function(){
      $scope = angular.element(document.getElementById('content')).scope();

      this.account = {
        first_name: $scope.first_name,
        last_name: $scope.last_name,
        email: $scope.email
      };

      var state = {
          note: this.note,
          notes: this.notes,
          updated: Date.now()
        },
        str = JSON.stringify(state);

      // Firebase
      str = this.encrypt(str);

      this.userRef.set({
        account: this.account,
        state: str
      }, function(){
        $location.path('/');
      });
    };

    /**
     * Updates a note
     */
    this.update = function(){
      var note = this.note,
          id = note.id || 0,
          now = Date.now();

      // ADD NOTE
      if(!id){
        id = (this.notes.length) ? _.max(this.notes, function(note){ return note.id; }).id++ : 1;

        note.id = id;
        note.created = now;
        note.updated = now;
        this.notes.unshift(note);
        this.show(note);

        $log.log('Adding Note...');
      // UPDATE NOTE
      }else{
        this.note.updated = now;

        $log.log('Updating Note...');
      }

      this.updated = now;
      this.save();
    };

    /**
     * Gets a note
     *
     * @param integer [id] The note id
     * @return object The note object
     */
    this.get = function(id){
      id = id || this.id;
      return _.findWhere(this.notes, {id: id});
    };

    /**
     * Adds a note
     */
    this.add = function(){
      this.note = {};
      this.save();
      $rootScope.$emit('load', this.notes, this.note);
    };

    /**
     * Removes a note
     *
     * @param integer|object [id=this.note] The note id or object
     */
    this.remove = function(id){
      if(typeof id === 'object' && id.id){
        id = id.id;
      }

      var note = (typeof id === 'number') ? _.findWhere(this.notes, {id: id}) : this.note;

      if(note){
          var $app = this;

          $mdDialog.show({
            templateUrl: 'views/dialogs/confirm.html',
            locals: {
              params: {
                title: 'Delete Note?',
                message: '
You are about to delete the note named...

'+note.name+'
',
                onOk: function(){
                  $app.notes = _.without($app.notes, note);
                  $app.note = undefined;
                  $app.save();
                  $rootScope.$emit('load', $app.notes, $app.note);
                },
                onCancel: function(){}
              }
            },
            parent: 'body',
            controller: ConfirmDialog
          });
      }
    };

    /**
     * Shows a note
     *
     * @param object note The note
     */
    this.show = function(note){
      var $app = this;
      this.note = note;
      //this.save();

      // Timeout used here because the main view needs time to load
      $timeout(function(){
        $rootScope.$emit('load', $app.notes, $app.note);
      }, 100);
    };

    /**
     * Saves the application state
     */
    this.save = function(){
      var state = {};

      // Build runtime state
      for(var prop in this.config){
        state[prop] = this[prop];
      }

      var str = JSON.stringify(state);

      // Firebase
      str = this.encrypt(str);
      this.stateRef.set(str);
      this.accountRef.set(this.account);
    };

    /**
     * Prompt to reload Firebase state
     */
    this.reload = function(){
      // Reload Firebase state
      if(this.snapshot && !this.reloading){
        this.reloading = true;
        var state, str = this.snapshot.val();

        str = this.decrypt(str);

        if(/^\{/.test(str)){
          state = JSON.parse(str);

          if(state.updated > this.updated){

            var $modal = $('#modal-confirm');
            $('.modal-title', $modal).text('Reload?');
            $('.modal-body', $modal).html('
A note was updated & saved remotely.
\
            Do you want to reload your local notes?
');

            $modal.off('hidden.bs.modal').on('hidden.bs.modal', function(e){
              $app.reloading = false;
            });

            $('.btn-yes', $modal).off('click').on('click', function(e){
              $modal.modal('hide');

              str = $app.snapshot.val();

              str = $app.decrypt(str);

              state = JSON.parse(str);

              // Fixes note hash keys
              for(var i=0; i<state.notes.length; i++){
                delete state.notes[i]['$$hashKey'];
              }

              this.notes = state.notes;

              // Fix note reference
              if(this.note && this.note.id){
                this.note = $scope.get(this.note.id);
              }

              this.$apply();

              $app.reloading = false;
            });

            $('.btn-no', $modal).off('click').on('click', function(e){
              $app.reloading = false;
            });

            $modal.modal();
          }else{
            $app.reloading = false;
          }
        }else{
          $app.reloading = false;
        }
      }
    };

    var $app = this;

    // Initial Page Load Authorization
    fb.onAuth(function(auth){
      if(auth){
        $log.info('Logged In...');
        $app.setAuth(auth);
      }else{
        $log.warn('Logged Out...');
        if(!/^\/signup\/?/.test($location.path())){
          $location.path('/login');
        }
      }
    });
  }
]);
<|endoftext|>


<commit_before>(function(angular) {
    'use strict';
    // angular.module('esri.map', []);

    /**
     * @description
     * Use `esriLoader` to lazyload the ESRI ArcGIS API or to require API modules.
     */
    angular.module('esri.map').factory('esriLoader', function ($q) {
        /**
         * Load the ESRI ArcGIS API
         * @memberof esriLoader
         * @param {Object} options Send a list of options of how to load the API.
         * @param {String} options.url the url to load the ESRI API, defaults to http://js.arcgis.com/3.14compact
         * @return {Promise} Returns a $q style which is resolved once the ESRI API has loaded.
         */
        function bootstrap(options) {
          var deferred = $q.defer();

          // Don't reload API if it is already loaded
          if ( angular.isDefined(window.esri) ) {
            deferred.reject('ESRI API is already loaded.');
          }

          // Default options object to empty hash
          options = angular.isDefined(options) ? options : {};

          // Create Script Object to be loaded
          var script    = document.createElement('script');
          script.type   = 'text/javascript';
          script.src    = options.url || 'http://js.arcgis.com/3.14compact';

          // Set onload callback to resolve promise
          script.onload = function() { deferred.resolve( window.esri ); };

          document.body.appendChild(script);

          return deferred.promise;
        }

        /** Check if the ESRI ArcGIS API is loaded
         * @return {Boolean} Returns a boolean if ESRI ArcGIS ASK is, in fact, loaded
         */
        function isLoaded() {
          return angular.isDefined(window.esri);
        }

        /**
         * Load ESRI Module, this will use dojo's AMD loader
         *
         * @param {String|Array} modules A string of a module or an array of modules to be loaded.
         * @param {Function} optional callback function used to support AMD style loading, promise and callback are both add to the event loop, possible race condition.
         * @return {Promise} Returns a $q style promise which is resolved once modules are loaded
         */
        function requireModule(moduleName, callback){
          var deferred = $q.defer();

          // Throw Error if ESRI is not loaded yet
          if ( !isLoaded() ) {
            deferred.reject('Trying to call esriLoader.require(), but esri API has not been loaded yet. Run esriLoader.bootstrap() if you are lazy loading esri ArcGIS API.');
            return deferred.promise;
          }
          if (angular.isString(moduleName)) {
            require([moduleName], function (module) {

              // Check if callback exists, and execute if it does
              if ( callback && angular.isFunction(callback) ) {
                  callback(module);
              }
              deferred.resolve(module);
            });
          }
          else if (angular.isArray(moduleName)) {
            require(moduleName, function () {

              var args = Array.prototype.slice.call(arguments);

              // callback check, sends modules loaded as arguments
              if ( callback && angular.isFunction(callback) ) {
                  callback.apply(this, args);
              }

              // Grab all of the modules pass back from require callback and send as array to promise.
              deferred.resolve(args);
            });
          }
          else {
            deferred.reject('An Array<String> or String is required to load modules.');
          }

          return deferred.promise;
        }

        // Return list of aformentioned functions
        return {
            bootstrap: bootstrap,
            isLoaded:  isLoaded,
            require:   requireModule
        };
    });

})(angular);
<commit_msg>docs(esriLoader): add memberof tags to methods of esriLoader<commit_after>(function(angular) {
    'use strict';
    // angular.module('esri.map', []);

    /**
     * @description
     * Use `esriLoader` to lazyload the ESRI ArcGIS API or to require API modules.
     */
    angular.module('esri.map').factory('esriLoader', function ($q) {
        /**
         * Load the ESRI ArcGIS API
         * @memberof esriLoader
         * @param {Object} options Send a list of options of how to load the API.
         * @param {String} options.url the url to load the ESRI API, defaults to http://js.arcgis.com/3.14compact
         * @return {Promise} Returns a $q style which is resolved once the ESRI API has loaded.
         */
        function bootstrap(options) {
          var deferred = $q.defer();

          // Don't reload API if it is already loaded
          if ( angular.isDefined(window.esri) ) {
            deferred.reject('ESRI API is already loaded.');
          }

          // Default options object to empty hash
          options = angular.isDefined(options) ? options : {};

          // Create Script Object to be loaded
          var script    = document.createElement('script');
          script.type   = 'text/javascript';
          script.src    = options.url || 'http://js.arcgis.com/3.14compact';

          // Set onload callback to resolve promise
          script.onload = function() { deferred.resolve( window.esri ); };

          document.body.appendChild(script);

          return deferred.promise;
        }

        /** Check if the ESRI ArcGIS API is loaded
         * @memberof esriLoader
         * @return {Boolean} Returns a boolean if ESRI ArcGIS ASK is, in fact, loaded
         */
        function isLoaded() {
          return angular.isDefined(window.esri);
        }

        /**
         * Load ESRI Module, this will use dojo's AMD loader
         * @memberof esriLoader
         * @param {String|Array} modules A string of a module or an array of modules to be loaded.
         * @param {Function} optional callback function used to support AMD style loading, promise and callback are both add to the event loop, possible race condition.
         * @return {Promise} Returns a $q style promise which is resolved once modules are loaded
         */
        function requireModule(moduleName, callback){
          var deferred = $q.defer();

          // Throw Error if ESRI is not loaded yet
          if ( !isLoaded() ) {
            deferred.reject('Trying to call esriLoader.require(), but esri API has not been loaded yet. Run esriLoader.bootstrap() if you are lazy loading esri ArcGIS API.');
            return deferred.promise;
          }
          if (angular.isString(moduleName)) {
            require([moduleName], function (module) {

              // Check if callback exists, and execute if it does
              if ( callback && angular.isFunction(callback) ) {
                  callback(module);
              }
              deferred.resolve(module);
            });
          }
          else if (angular.isArray(moduleName)) {
            require(moduleName, function () {

              var args = Array.prototype.slice.call(arguments);

              // callback check, sends modules loaded as arguments
              if ( callback && angular.isFunction(callback) ) {
                  callback.apply(this, args);
              }

              // Grab all of the modules pass back from require callback and send as array to promise.
              deferred.resolve(args);
            });
          }
          else {
            deferred.reject('An Array<String> or String is required to load modules.');
          }

          return deferred.promise;
        }

        // Return list of aformentioned functions
        return {
            bootstrap: bootstrap,
            isLoaded:  isLoaded,
            require:   requireModule
        };
    });

})(angular);
<|endoftext|>


<commit_before>/*!
 *  Chinachu Common Module (node-chinachu-common)
 *
 *  Copyright (c) 2012 Yuki KAN and Chinachu Project Contributors
 *  http://chinachu.akkar.in/
**/
/*jslint node:true, nomen:true, plusplus:true, regexp:true, vars:true */
'use strict';

var fs         = require('fs');
var crypto     = require('crypto');
var dateFormat = require('dateformat');

exports.jsonWatcher = function (filepath, callback, option) {
	if (typeof option === 'undefined') { option = {}; }

	option.wait = option.wait || 1000;

	if (!fs.existsSync(filepath)) {
		if (option.create) {
			fs.writeFileSync(filepath, JSON.stringify(option.create));
		} else {
			callback('FATAL: `' + filepath + '` is not exists.', null, null);
			return;
		}
	}

	function read() {
		try {
			if (typeof require.cache[filepath] !== 'undefined') {
				delete require.cache[filepath];
			}

			var data = require(filepath);
			callback(null, data, 'READ: `' + filepath + '` is updated.');
		} catch (e) {
			callback('WARN: `' + filepath + '` is invalid. (' + e + ')', null, null);
		}
	}

	if (option.now) { read(); }

	var timer;
	function onUpdated() {
		clearTimeout(timer);
		timer = setTimeout(read, option.wait);
	}
	fs.watch(filepath, onUpdated);
};

exports.getProgramById = function (id, array) {
	if (!array || array.length === 0) {
		return null;
	}

	if (array[0].programs) {
		array = (function () {
			var programs = [];

			array.forEach(function (ch) {
				programs = programs.concat(ch.programs);
			});

			return programs;
		}());
	}

	return (function () {
		var x = null;

		array.forEach(function (a) {
			if (a.id === id) { x = a; }
		});

		return x;
	}());
};

exports.existsTuner = function (tuners, type, callback) {

	process.nextTick(function () {
		callback(exports.existsTunerSync(tuners, type));
	});
};

exports.existsTunerSync = function (tuners, type) {

	var j, tuner, isExists = false;

	for (j = 0; tuners.length > j; j++) {
		tuner = tuners[j];
		tuner.n = j;

		if (tuner.types.indexOf(type) !== -1) {
			isExists = true;
			break;
		}
	}

	return isExists;
};

exports.getFreeTunerSync = function (tuners, type) {

	var j, tuner, freeTuner = null;

	for (j = 0; tuners.length > j; j++) {
		tuner = tuners[j];
		tuner.n = j;

		if ((tuner.types.indexOf(type) !== -1) && (fs.existsSync('./data/tuner.' + j + '.lock') === false)) {
			freeTuner = tuner;
			break;
		}
	}

	return freeTuner;
};

exports.lockTuner = function (tuner, callback) {
	fs.writeFile('./data/tuner.' + tuner.n + '.lock', '', { flag: 'wx' }, callback);
};

exports.lockTunerSync = function (tuner) {
	try {
		return fs.writeFileSync('./data/tuner.' + tuner.n + '.lock', '', { flag: 'wx' });
	} catch (e) {
		throw e;
	}
};

exports.unlockTuner = function (tuner, callback) {
	fs.unlink('./data/tuner.' + tuner.n + '.lock', callback);
};

exports.unlockTunerSync = function (tuner) {
	return fs.unlinkSync('./data/tuner.' + tuner.n + '.lock');
};

var Countdown = function (count, callback) {
	this.c = count;
	this.f = callback;
};

Countdown.prototype = {
	tick: function () {

		--this.c;

		if (this.c === 0) {
			this.f();
		}

		return this;
	}
};

exports.createCountdown = function (a, b) {
	return new Countdown(a, b);
};

exports.createTimeout = function (a, b) {
	return function () {
		return setTimeout(a, b);
	};
};

exports.formatRecordedName = function (program, name) {
	name = name.replace(/<([^>]+)>/g, function (z, a) {

		// date:
		if (a.match(/^date:.+$/) !== null) { return dateFormat(new Date(program.start), a.match(/:(.+)$/)[1]); }

		// id
		if (a.match(/^id$/) !== null) { return program.id; }

		// type
		if (a.match(/^type$/) !== null) { return program.channel.type; }

		// channel
		if (a.match(/^channel$/) !== null) { return program.channel.channel; }

		// channel-id
		if (a.match(/^channel-id$/) !== null) { return program.channel.id; }

		// channel-sid
		if (a.match(/^channel-sid$/) !== null) { return program.channel.sid; }

		// channel-name
		if (a.match(/^channel-name$/) !== null) { return exports.stripFilename(program.channel.name); }

		// tuner
		if (a.match(/^tuner$/) !== null) { return program.tuner.name; }

		// title
		if (a.match(/^title$/) !== null) { return exports.stripFilename(program.title); }

		// fulltitle
		if (a.match(/^fulltitle$/) !== null) { return exports.stripFilename(program.fullTitle || ''); }

		// subtitle
		if (a.match(/^subtitle$/) !== null) { return exports.stripFilename(program.subTitle || ''); }

		// episode
		if (a.match(/^episode$/) !== null) { return program.episode || 'n'; }

		// category
		if (a.match(/^category$/) !== null) { return program.category; }
	});

	return name;
};

// strip
exports.stripFilename = function (a) {

	a = a.replace(/\//g, '／').replace(/\\/g, '＼').replace(/:/g, '：').replace(/\*/g, '＊').replace(/\?/g, '？');
	a = a.replace(/"/g, '”').replace(/</g, '＜').replace(/>/g, '＞').replace(/\|/g, '｜').replace(/≫/g, '＞＞');

	return a;
};

exports.isMatchedProgram = function (rules, program) {
	var result = false;

	rules.forEach(function (rule) {

		var i, j, l, m, isFound;

		// isDisabled
		if (rule.isDisabled) { return; }

		// sid
		if (rule.sid && rule.sid !== program.channel.sid) { return; }

		// types
		if (rule.types) {
			if (rule.types.indexOf(program.channel.type) === -1) { return; }
		}

		// channels
		if (rule.channels) {
			if (rule.channels.indexOf(program.channel.id) === -1) {
				if (rule.channels.indexOf(program.channel.channel) === -1) {
					return;
				}
			}
		}

		// ignore_channels
		if (rule.ignore_channels) {
			if (rule.ignore_channels.indexOf(program.channel.id) !== -1) {
				return;
			}
			if (rule.ignore_channels.indexOf(program.channel.channel) !== -1) {
				return;
			}
		}

		// category
		if (rule.category && rule.category !== program.category) { return; }

		// categories
		if (rule.categories) {
			if (rule.categories.indexOf(program.category) === -1) { return; }
		}

		// hour
		if (rule.hour && (typeof rule.hour.start !== 'undefined') && (typeof rule.hour.end !== 'undefined')) {
			var ruleStart = rule.hour.start;
			var ruleEnd   = rule.hour.end;

			var progStart = new Date(program.start).getHours();
			var progEnd   = new Date(program.end).getHours();

			if (progStart > progEnd) {
				progEnd += 24;
			}

			if (ruleStart > ruleEnd) {
				if ((ruleStart > progStart) && (ruleEnd < progEnd)) { return; }
			} else {
				if ((ruleStart > progStart) || (ruleEnd < progEnd)) { return; }
			}
		}

		// duration
		if (rule.duration && (typeof rule.duration.min !== 'undefined') && (typeof rule.duration.max !== 'undefined')) {
			if ((rule.duration.min > program.seconds) || (rule.duration.max < program.seconds)) { return; }
		}

		// ignore_titles
		if (rule.ignore_titles) {
			for (i = 0; i < rule.ignore_titles.length; i++) {
				if (program.fullTitle.match(rule.ignore_titles[i]) !== null) { return; }
			}
		}

		// reserve_titles
		if (rule.reserve_titles) {
			isFound = false;

			for (i = 0; i < rule.reserve_titles.length; i++) {
				if (program.fullTitle.match(rule.reserve_titles[i]) !== null) { isFound = true; }
			}

			if (!isFound) { return; }
		}

		// ignore_descriptions
		if (rule.ignore_descriptions) {
			if (!program.detail) { return; }

			for (i = 0; i < rule.ignore_descriptions.length; i++) {
				if (program.detail.match(rule.ignore_descriptions[i]) !== null) { return; }
			}
		}

		// reserve_descriptions
		if (rule.reserve_descriptions) {
			if (!program.detail) { return; }

			isFound = false;

			for (i = 0; i < rule.reserve_descriptions.length; i++) {
				if (program.detail.match(rule.reserve_descriptions[i]) !== null) { isFound = true; }
			}

			if (!isFound) { return; }
		}

		// ignore_flags
		if (rule.ignore_flags) {
			for (i = 0; i < rule.ignore_flags.length; i++) {
				for (j = 0; j < program.flags.length; j++) {
					if (rule.ignore_flags[i] === program.flags[j]) { return; }
				}
			}
		}

		// reserve_flags
		if (rule.reserve_flags) {
			if (!program.flags) { return; }

			isFound = false;

			for (i = 0; i < rule.reserve_flags.length; i++) {
				for (j = 0; j < program.flags.length; j++) {
					if (rule.reserve_flags[i] === program.flags[j]) { isFound = true; }
				}
			}

			if (!isFound) { return; }
		}

		result = true;

	});

	return result;
};<commit_msg>common#isMatchedProgram: 不具合の修正 #59<commit_after>/*!
 *  Chinachu Common Module (node-chinachu-common)
 *
 *  Copyright (c) 2012 Yuki KAN and Chinachu Project Contributors
 *  http://chinachu.akkar.in/
**/
/*jslint node:true, nomen:true, plusplus:true, regexp:true, vars:true */
'use strict';

var fs         = require('fs');
var crypto     = require('crypto');
var dateFormat = require('dateformat');

exports.jsonWatcher = function (filepath, callback, option) {
	if (typeof option === 'undefined') { option = {}; }

	option.wait = option.wait || 1000;

	if (!fs.existsSync(filepath)) {
		if (option.create) {
			fs.writeFileSync(filepath, JSON.stringify(option.create));
		} else {
			callback('FATAL: `' + filepath + '` is not exists.', null, null);
			return;
		}
	}

	function read() {
		try {
			if (typeof require.cache[filepath] !== 'undefined') {
				delete require.cache[filepath];
			}

			var data = require(filepath);
			callback(null, data, 'READ: `' + filepath + '` is updated.');
		} catch (e) {
			callback('WARN: `' + filepath + '` is invalid. (' + e + ')', null, null);
		}
	}

	if (option.now) { read(); }

	var timer;
	function onUpdated() {
		clearTimeout(timer);
		timer = setTimeout(read, option.wait);
	}
	fs.watch(filepath, onUpdated);
};

exports.getProgramById = function (id, array) {
	if (!array || array.length === 0) {
		return null;
	}

	if (array[0].programs) {
		array = (function () {
			var programs = [];

			array.forEach(function (ch) {
				programs = programs.concat(ch.programs);
			});

			return programs;
		}());
	}

	return (function () {
		var x = null;

		array.forEach(function (a) {
			if (a.id === id) { x = a; }
		});

		return x;
	}());
};

exports.existsTuner = function (tuners, type, callback) {

	process.nextTick(function () {
		callback(exports.existsTunerSync(tuners, type));
	});
};

exports.existsTunerSync = function (tuners, type) {

	var j, tuner, isExists = false;

	for (j = 0; tuners.length > j; j++) {
		tuner = tuners[j];
		tuner.n = j;

		if (tuner.types.indexOf(type) !== -1) {
			isExists = true;
			break;
		}
	}

	return isExists;
};

exports.getFreeTunerSync = function (tuners, type) {

	var j, tuner, freeTuner = null;

	for (j = 0; tuners.length > j; j++) {
		tuner = tuners[j];
		tuner.n = j;

		if ((tuner.types.indexOf(type) !== -1) && (fs.existsSync('./data/tuner.' + j + '.lock') === false)) {
			freeTuner = tuner;
			break;
		}
	}

	return freeTuner;
};

exports.lockTuner = function (tuner, callback) {
	fs.writeFile('./data/tuner.' + tuner.n + '.lock', '', { flag: 'wx' }, callback);
};

exports.lockTunerSync = function (tuner) {
	try {
		return fs.writeFileSync('./data/tuner.' + tuner.n + '.lock', '', { flag: 'wx' });
	} catch (e) {
		throw e;
	}
};

exports.unlockTuner = function (tuner, callback) {
	fs.unlink('./data/tuner.' + tuner.n + '.lock', callback);
};

exports.unlockTunerSync = function (tuner) {
	return fs.unlinkSync('./data/tuner.' + tuner.n + '.lock');
};

var Countdown = function (count, callback) {
	this.c = count;
	this.f = callback;
};

Countdown.prototype = {
	tick: function () {

		--this.c;

		if (this.c === 0) {
			this.f();
		}

		return this;
	}
};

exports.createCountdown = function (a, b) {
	return new Countdown(a, b);
};

exports.createTimeout = function (a, b) {
	return function () {
		return setTimeout(a, b);
	};
};

exports.formatRecordedName = function (program, name) {
	name = name.replace(/<([^>]+)>/g, function (z, a) {

		// date:
		if (a.match(/^date:.+$/) !== null) { return dateFormat(new Date(program.start), a.match(/:(.+)$/)[1]); }

		// id
		if (a.match(/^id$/) !== null) { return program.id; }

		// type
		if (a.match(/^type$/) !== null) { return program.channel.type; }

		// channel
		if (a.match(/^channel$/) !== null) { return program.channel.channel; }

		// channel-id
		if (a.match(/^channel-id$/) !== null) { return program.channel.id; }

		// channel-sid
		if (a.match(/^channel-sid$/) !== null) { return program.channel.sid; }

		// channel-name
		if (a.match(/^channel-name$/) !== null) { return exports.stripFilename(program.channel.name); }

		// tuner
		if (a.match(/^tuner$/) !== null) { return program.tuner.name; }

		// title
		if (a.match(/^title$/) !== null) { return exports.stripFilename(program.title); }

		// fulltitle
		if (a.match(/^fulltitle$/) !== null) { return exports.stripFilename(program.fullTitle || ''); }

		// subtitle
		if (a.match(/^subtitle$/) !== null) { return exports.stripFilename(program.subTitle || ''); }

		// episode
		if (a.match(/^episode$/) !== null) { return program.episode || 'n'; }

		// category
		if (a.match(/^category$/) !== null) { return program.category; }
	});

	return name;
};

// strip
exports.stripFilename = function (a) {

	a = a.replace(/\//g, '／').replace(/\\/g, '＼').replace(/:/g, '：').replace(/\*/g, '＊').replace(/\?/g, '？');
	a = a.replace(/"/g, '”').replace(/</g, '＜').replace(/>/g, '＞').replace(/\|/g, '｜').replace(/≫/g, '＞＞');

	return a;
};

exports.isMatchedProgram = function (rules, program) {
	var result = false;

	rules.forEach(function (rule) {

		var i, j, l, m, isFound;

		// isDisabled
		if (rule.isDisabled) { return; }

		// sid
		if (rule.sid && rule.sid !== program.channel.sid) { return; }

		// types
		if (rule.types) {
			if (rule.types.indexOf(program.channel.type) === -1) { return; }
		}

		// channels
		if (rule.channels) {
			if (rule.channels.indexOf(program.channel.id) === -1) {
				if (rule.channels.indexOf(program.channel.channel) === -1) {
					return;
				}
			}
		}

		// ignore_channels
		if (rule.ignore_channels) {
			if (rule.ignore_channels.indexOf(program.channel.id) !== -1) {
				return;
			}
			if (rule.ignore_channels.indexOf(program.channel.channel) !== -1) {
				return;
			}
		}

		// category
		if (rule.category && rule.category !== program.category) { return; }

		// categories
		if (rule.categories) {
			if (rule.categories.indexOf(program.category) === -1) { return; }
		}

		// hour
		if (rule.hour && (typeof rule.hour.start !== 'undefined') && (typeof rule.hour.end !== 'undefined')) {
			var ruleStart = rule.hour.start;
			var ruleEnd   = rule.hour.end;

			var progStart = new Date(program.start).getHours();
			var progEnd   = new Date(program.end).getHours();

			if (progStart > progEnd) {
				progEnd += 24;
			}

			if (ruleStart > ruleEnd) {
				if ((ruleStart > progStart) && (ruleEnd < progEnd)) { return; }
			} else {
				if ((ruleStart > progStart) || (ruleEnd < progEnd)) { return; }
			}
		}

		// duration
		if (rule.duration && (typeof rule.duration.min !== 'undefined') && (typeof rule.duration.max !== 'undefined')) {
			if ((rule.duration.min > program.seconds) || (rule.duration.max < program.seconds)) { return; }
		}

		// reserve_titles
		if (rule.reserve_titles) {
			isFound = false;

			for (i = 0; i < rule.reserve_titles.length; i++) {
				if (program.fullTitle.match(rule.reserve_titles[i]) !== null) { isFound = true; }
			}

			if (!isFound) { return; }
		}

		// ignore_titles
		if (rule.ignore_titles) {
			for (i = 0; i < rule.ignore_titles.length; i++) {
				if (program.fullTitle.match(rule.ignore_titles[i]) !== null) { return; }
			}
		}

		// reserve_descriptions
		if (rule.reserve_descriptions) {
			if (!program.detail) { return; }

			isFound = false;

			for (i = 0; i < rule.reserve_descriptions.length; i++) {
				if (program.detail.match(rule.reserve_descriptions[i]) !== null) { isFound = true; }
			}

			if (!isFound) { return; }
		}

		// ignore_descriptions
		if (rule.ignore_descriptions) {
			if (!program.detail) { return; }

			for (i = 0; i < rule.ignore_descriptions.length; i++) {
				if (program.detail.match(rule.ignore_descriptions[i]) !== null) { return; }
			}
		}

		// ignore_flags
		if (rule.ignore_flags) {
			for (i = 0; i < rule.ignore_flags.length; i++) {
				for (j = 0; j < program.flags.length; j++) {
					if (rule.ignore_flags[i] === program.flags[j]) { return; }
				}
			}
		}

		// reserve_flags
		if (rule.reserve_flags) {
			if (!program.flags) { return; }

			isFound = false;

			for (i = 0; i < rule.reserve_flags.length; i++) {
				for (j = 0; j < program.flags.length; j++) {
					if (rule.reserve_flags[i] === program.flags[j]) { isFound = true; }
				}
			}

			if (!isFound) { return; }
		}

		result = true;

	});

	return result;
};<|endoftext|>


<commit_before>(function() {
/* Start angularLocalStorage */
'use strict';
var angularLocalStorage = angular.module('LocalStorageModule', []);

angularLocalStorage.provider('localStorageService', function(){
  // You should set a prefix to avoid overwriting any local storage variables from the rest of your app
  // e.g. angularLocalStorage.constant('prefix', 'youAppName');
  this.prefix = 'ls';
  // Cookie options (usually in case of fallback)
  // expiry = Number of days before cookies expire // 0 = Does not expire
  // path = The web path the cookie represents
  this.cookie = {
    expiry: 30,
    path: '/'
  };
  this.notify = {
    setItem: true,
    removeItem: false
  };
  this.setPrefix = function(prefix){
    this.prefix = prefix;
  };
  this.setStorageCookie = function(exp, path){
    this.cookie = {
      expiry: exp,
      path: path
    };
  };
  this.setNotify = function(itemSet, itemRemove){
    this.notify = {
      setItem: itemSet,
      removeItem: itemRemove
    };
  };

  this.$get = ['$rootScope',function($rootScope){

    var prefix = this.prefix;
    // If there is a prefix set in the config lets use that with an appended period for readability
    if (prefix.substr(-1)!=='.') {
        prefix = !!prefix ? prefix + '.' : '';
    }

    // Checks the browser to see if local storage is supported
    var browserSupportsLocalStorage = function () {
      try {
        var supported = ('localStorage' in window && window['localStorage'] !== null);

        // When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage
        // is available, but trying to call .setItem throws an exception.
        //
        // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage
        // that exceeded the quota."
        var key = prefix + '__' + Math.round(Math.random() * 1e7);
        if (supported) {
          localStorage.setItem(key, '');
          localStorage.removeItem(key);
        }

        return true;
      } catch (e) {
        $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
        return false;
      }
    };

                // If this browser does not support local storage use cookies
                if (!browserSupportsLocalStorage()) {
                    $rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
                    if (notify.setItem) {
                        $rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'cookie'});
                    }
                    return addToCookies(key, value);
                }

                // Let's convert undefined values to null to get the value consistent
                if (typeof value === "undefined") {
                    value = null;
                }

                try {
                    if (angular.isObject(value) || angular.isArray(value)) {
                        value = angular.toJson(value);
                    }
                    localStorage.setItem(prefix+key, value);
                    if (notify.setItem) {
                        $rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'localStorage'});
                    }
                } catch (e) {
                    $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
                    return addToCookies(key, value);
                }
                return true;
            };

            // Directly get a value from local storage
            // Example use: localStorageService.get('library'); // returns 'angular'
            var getFromLocalStorage = function (key) {
                if (!browserSupportsLocalStorage()) {
                    $rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
                    return getFromCookies(key);
                }

                var item = localStorage.getItem(prefix+key);
                // angular.toJson will convert null to 'null', so a proper conversion is needed
                // FIXME not a perfect solution, since a valid 'null' string can't be stored
                if (!item || item === 'null') {return null;}

                if (item.charAt(0) === "{" || item.charAt(0) === "[") {
                    return angular.fromJson(item);
                }
                return item;
            };

            // Remove an item from local storage
            // Example use: localStorageService.remove('library'); // removes the key/value pair of library='angular'
            var removeFromLocalStorage = function (key) {
                if (!browserSupportsLocalStorage()) {
                    $rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
                    if (notify.removeItem) {
                        $rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'cookie'});
                    }
                    return removeFromCookies(key);
                }

                try {
                    localStorage.removeItem(prefix+key);
                    if (notify.removeItem) {
                        $rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'localStorage'});
                    }
                } catch (e) {
                    $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
                    return removeFromCookies(key);
                }
                return true;
            };

            // Return array of keys for local storage
            // Example use: var keys = localStorageService.keys()
            var getKeysForLocalStorage = function () {

                if (!browserSupportsLocalStorage()) {
                    $rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
                    return false;
                }

                var prefixLength = prefix.length;
                var keys = [];
                for (var key in localStorage) {
                    // Only return keys that are for this app
                    if (key.substr(0,prefixLength) === prefix) {
                        try {
                            keys.push(key.substr(prefixLength));
                        } catch (e) {
                            $rootScope.$broadcast('LocalStorageModule.notification.error',e.Description);
                            return [];
                        }
                    }
                }
                return keys;
            };

            // Remove all data for this app from local storage
            // Example use: localStorageService.clearAll();
            // Should be used mostly for development purposes
            var clearAllFromLocalStorage = function () {

                if (!browserSupportsLocalStorage()) {
                    $rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
                    return clearAllFromCookies();
                }

                var prefixLength = prefix.length;

                for (var key in localStorage) {
                    // Only remove items that are for this app
                    if (key.substr(0,prefixLength) === prefix) {
                        try {
                            removeFromLocalStorage(key.substr(prefixLength));
                        } catch (e) {
                            $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
                            return clearAllFromCookies();
                        }
                    }
                }
                return true;
            };

            // Checks the browser to see if cookies are supported
            var browserSupportsCookies = function() {
                try {
                    return navigator.cookieEnabled ||
                        ("cookie" in document && (document.cookie.length > 0 ||
                            (document.cookie = "test").indexOf.call(document.cookie, "test") > -1));
                } catch (e) {
                    $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
                    return false;
                }
            };

            // Directly adds a value to cookies
            // Typically used as a fallback is local storage is not available in the browser
            // Example use: localStorageService.cookie.add('library','angular');
            var addToCookies = function (key, value) {

                if (typeof value === "undefined") {
                    return false;
                }

                if (!browserSupportsCookies()) {
                    $rootScope.$broadcast('LocalStorageModule.notification.error','COOKIES_NOT_SUPPORTED');
                    return false;
                }

                try {
                    var expiry = '', expiryDate = new Date();
                    if (value === null) {
                        // Mark that the cookie has expired one day ago
                        expiryDate.setTime(expiryDate.getTime() + (-1 * 24*60*60*1000));
                        expiry = "; expires="+expiryDate.toGMTString();

                        value = '';
                    } else if (cookie.expiry !== 0) {
                        expiryDate.setTime(expiryDate.getTime() + (cookie.expiry*24*60*60*1000));
                        expiry = "; expires="+expiryDate.toGMTString();
                    }
                    if (!!key) {
                        document.cookie = prefix + key + "=" + encodeURIComponent(value) + expiry + "; path="+cookie.path;
                    }
                } catch (e) {
                    $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
                    return false;
                }
                return true;
            };

            // Directly get a value from a cookie
            // Example use: localStorageService.cookie.get('library'); // returns 'angular'
            var getFromCookies = function (key) {
                if (!browserSupportsCookies()) {
                    $rootScope.$broadcast('LocalStorageModule.notification.error','COOKIES_NOT_SUPPORTED');
                    return false;
                }

                var cookies = document.cookie.split(';');
                for(var i=0;i < cookies.length;i++) {
                    var thisCookie = cookies[i];
                    while (thisCookie.charAt(0)===' ') {
                        thisCookie = thisCookie.substring(1,thisCookie.length);
                    }
                    if (thisCookie.indexOf(prefix+key+'=') === 0) {
                        return decodeURIComponent(thisCookie.substring(prefix.length+key.length+1,thisCookie.length));
                    }
                }
                return null;
            };

            var removeFromCookies = function (key) {
                addToCookies(key,null);
            };

            var clearAllFromCookies = function () {
                var thisCookie = null, thisKey = null;
                var prefixLength = prefix.length;
                var cookies = document.cookie.split(';');
                for(var i=0;i < cookies.length;i++) {
                    thisCookie = cookies[i];
                    while (thisCookie.charAt(0)===' ') {
                        thisCookie = thisCookie.substring(1,thisCookie.length);
                    }
                    key = thisCookie.substring(prefixLength,thisCookie.indexOf('='));
                    removeFromCookies(key);
                }
            };

            return {
                isSupported: browserSupportsLocalStorage,
                set: addToLocalStorage,
                add: addToLocalStorage, //DEPRECATED
                get: getFromLocalStorage,
                keys: getKeysForLocalStorage,
                remove: removeFromLocalStorage,
                clearAll: clearAllFromLocalStorage,
                cookie: {
                    set: addToCookies,
                    add: addToCookies, //DEPRECATED
                    get: getFromCookies,
                    remove: removeFromCookies,
                    clearAll: clearAllFromCookies
                }
            };
        }]
    });
}).call(this);<commit_msg>Fixed JS error from merge and changed spacing<commit_after>(function() {
/* Start angularLocalStorage */
'use strict';
var angularLocalStorage = angular.module('LocalStorageModule', []);

angularLocalStorage.provider('localStorageService', function(){
  // You should set a prefix to avoid overwriting any local storage variables from the rest of your app
  // e.g. angularLocalStorage.constant('prefix', 'youAppName');
  this.prefix = 'ls';
  // Cookie options (usually in case of fallback)
  // expiry = Number of days before cookies expire // 0 = Does not expire
  // path = The web path the cookie represents
  this.cookie = {
    expiry: 30,
    path: '/'
  };
  this.notify = {
    setItem: true,
    removeItem: false
  };
  this.setPrefix = function(prefix){
    this.prefix = prefix;
  };
  this.setStorageCookie = function(exp, path){
    this.cookie = {
      expiry: exp,
      path: path
    };
  };
  this.setNotify = function(itemSet, itemRemove){
    this.notify = {
      setItem: itemSet,
      removeItem: itemRemove
    };
  };

  this.$get = ['$rootScope', function($rootScope){

    var prefix = this.prefix;
    // If there is a prefix set in the config lets use that with an appended period for readability
    if (prefix.substr(-1) !== '.') {
      prefix = !!prefix ? prefix + '.' : '';
    }

    // Checks the browser to see if local storage is supported
    var browserSupportsLocalStorage = function () {
      try {
        var supported = ('localStorage' in window && window['localStorage'] !== null);

        // When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage
        // is available, but trying to call .setItem throws an exception.
        //
        // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage
        // that exceeded the quota."
        var key = prefix + '__' + Math.round(Math.random() * 1e7);
        if (supported) {
          localStorage.setItem(key, '');
          localStorage.removeItem(key);
        }

        return true;
      } catch (e) {
        $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
        return false;
      }
    };

    // Directly adds a value to local storage
    // If local storage is not available in the browser use cookies
    // Example use: localStorageService.add('library','angular');
    var addToLocalStorage = function (key, value) {

      // If this browser does not support local storage use cookies
      if (!browserSupportsLocalStorage()) {
        $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
        if (notify.setItem) {
          $rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'cookie'});
        }
        return addToCookies(key, value);
      }

      // Let's convert undefined values to null to get the value consistent
      if (typeof value === "undefined") {
        value = null;
      }

      try {
        if (angular.isObject(value) || angular.isArray(value)) {
          value = angular.toJson(value);
        }
        localStorage.setItem(prefix + key, value);
        if (notify.setItem) {
          $rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'localStorage'});
        }
      } catch (e) {
        $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
        return addToCookies(key, value);
      }
      return true;
    };

    // Directly get a value from local storage
    // Example use: localStorageService.get('library'); // returns 'angular'
    var getFromLocalStorage = function (key) {

      if (!browserSupportsLocalStorage()) {
        $rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
        return getFromCookies(key);
      }

      var item = localStorage.getItem(prefix + key);
      // angular.toJson will convert null to 'null', so a proper conversion is needed
      // FIXME not a perfect solution, since a valid 'null' string can't be stored
      if (!item || item === 'null') {
        return null;
      }

      if (item.charAt(0) === "{" || item.charAt(0) === "[") {
        return angular.fromJson(item);
      }

      return item;
    };

    // Remove an item from local storage
    // Example use: localStorageService.remove('library'); // removes the key/value pair of library='angular'
    var removeFromLocalStorage = function (key) {
      if (!browserSupportsLocalStorage()) {
        $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
        if (notify.removeItem) {
          $rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'cookie'});
        }
        return removeFromCookies(key);
      }

      try {
        localStorage.removeItem(prefix+key);
        if (notify.removeItem) {
          $rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'localStorage'});
        }
      } catch (e) {
        $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
        return removeFromCookies(key);
      }
      return true;
    };

    // Return array of keys for local storage
    // Example use: var keys = localStorageService.keys()
    var getKeysForLocalStorage = function () {

      if (!browserSupportsLocalStorage()) {
        $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
        return false;
      }

      var prefixLength = prefix.length;
      var keys = [];
      for (var key in localStorage) {
        // Only return keys that are for this app
        if (key.substr(0,prefixLength) === prefix) {
          try {
            keys.push(key.substr(prefixLength));
          } catch (e) {
            $rootScope.$broadcast('LocalStorageModule.notification.error', e.Description);
            return [];
          }
        }
      }
      return keys;
    };

    // Remove all data for this app from local storage
    // Example use: localStorageService.clearAll();
    // Should be used mostly for development purposes
    var clearAllFromLocalStorage = function () {

      if (!browserSupportsLocalStorage()) {
        $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
        return clearAllFromCookies();
      }

      var prefixLength = prefix.length;

      for (var key in localStorage) {
        // Only remove items that are for this app
        if (key.substr(0,prefixLength) === prefix) {
          try {
            removeFromLocalStorage(key.substr(prefixLength));
          } catch (e) {
            $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
            return clearAllFromCookies();
          }
        }
      }
      return true;
    };

    // Checks the browser to see if cookies are supported
    var browserSupportsCookies = function() {
      try {
        return navigator.cookieEnabled ||
          ("cookie" in document && (document.cookie.length > 0 ||
          (document.cookie = "test").indexOf.call(document.cookie, "test") > -1));
      } catch (e) {
          $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
          return false;
      }
    };

    // Directly adds a value to cookies
    // Typically used as a fallback is local storage is not available in the browser
    // Example use: localStorageService.cookie.add('library','angular');
    var addToCookies = function (key, value) {

      if (typeof value === "undefined") {
        return false;
      }

      if (!browserSupportsCookies()) {
        $rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
        return false;
      }

      try {
        var expiry = '',
            expiryDate = new Date();

        if (value === null) {
          // Mark that the cookie has expired one day ago
          expiryDate.setTime(expiryDate.getTime() + (-1 * 24 * 60 * 60 * 1000));
          expiry = "; expires=" + expiryDate.toGMTString();
          value = '';
        } else if (cookie.expiry !== 0) {
          expiryDate.setTime(expiryDate.getTime() + (cookie.expiry * 24 * 60 * 60 * 1000));
          expiry = "; expires=" + expiryDate.toGMTString();
        }
        if (!!key) {
          document.cookie = prefix + key + "=" + encodeURIComponent(value) + expiry + "; path="+cookie.path;
          }
      } catch (e) {
        $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
        return false;
      }
      return true;
    };

    // Directly get a value from a cookie
    // Example use: localStorageService.cookie.get('library'); // returns 'angular'
    var getFromCookies = function (key) {
      if (!browserSupportsCookies()) {
        $rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
        return false;
      }

      var cookies = document.cookie.split(';');
      for(var i=0;i < cookies.length;i++) {
        var thisCookie = cookies[i];
        while (thisCookie.charAt(0)===' ') {
          thisCookie = thisCookie.substring(1,thisCookie.length);
        }
        if (thisCookie.indexOf(prefix + key + '=') === 0) {
          return decodeURIComponent(thisCookie.substring(prefix.length + key.length + 1, thisCookie.length));
        }
      }
      return null;
    };

    var removeFromCookies = function (key) {
      addToCookies(key,null);
    };

    var clearAllFromCookies = function () {
      var thisCookie = null, thisKey = null;
      var prefixLength = prefix.length;
      var cookies = document.cookie.split(';');
      for(var i = 0; i < cookies.length; i++) {
        thisCookie = cookies[i];

        while (thisCookie.charAt(0) === ' ') {
          thisCookie = thisCookie.substring(1, thisCookie.length);
        }

        key = thisCookie.substring(prefixLength, thisCookie.indexOf('='));
        removeFromCookies(key);
      }
    };

    return {
      isSupported: browserSupportsLocalStorage,
      set: addToLocalStorage,
      add: addToLocalStorage, //DEPRECATED
      get: getFromLocalStorage,
      keys: getKeysForLocalStorage,
      remove: removeFromLocalStorage,
      clearAll: clearAllFromLocalStorage,
      cookie: {
        set: addToCookies,
        add: addToCookies, //DEPRECATED
        get: getFromCookies,
        remove: removeFromCookies,
        clearAll: clearAllFromCookies
      }
    };
  }]
});
}).call(this);<|endoftext|>


<commit_before>angular.module('toggle-switch', ['ng']).directive('toggleSwitch', function () {
    return {
        restrict: 'EA',
        replace: true,
        scope: {
            model: '=',
            on: '=',
            off: '='
        },
        template: '

{{ on || "On" }} {{ off || "Off" }}

',
        link: function ($scope, element, attrs) {
            if ($scope.model == null) {
                $scope.model = false;
            }
            return $scope.toggle = function () {
                element.children().addClass('switch-animate')
                return $scope.model = !$scope.model;
            };
        }
    };
});
<commit_msg>Style fixes Scope vars renamed to onLabel and offLabel<commit_after>angular.module('toggle-switch', ['ng']).directive('toggleSwitch', function () {
  return {
    restrict: 'EA',
    replace: true,
    scope: {
      model: '=',
      onLabel: '=on-label',
      offLabel: '=off-label'
    },
    template: '

{{ onLabel }} {{ offLabel }}

',
    link: function ($scope, element, attrs) {
      if ($scope.model == null) {
        $scope.model = false;
      }
      $scope.onLabel = $scope.onLabel || 'On'
      $scope.offLabel = $scope.offLabel || 'Off'
      return $scope.toggle = function () {
        element.children().addClass('switch-animate')
        return $scope.model = !$scope.model;
      };
    }
  };
});
<|endoftext|>