<commit_before>(function (angular) {
    'use strict';

    var app = angular.module('app');
    app.controller('albumsController', ['$scope', 'albumsService', 'authContext', '$state', function ($scope, albumsService, authContext, $state) {
        var self = this;

        self.albums=[];
        albumsService.getUserAlbums(authContext.userId).then(function (albums) {
            if (albums && angular.isArray(albums)) {
                self.albums = albums;
            }
        });
        $scope.$on('albumCreated', function (e,album) {
            self.albums.push(album);
        });
        self.goToAlbum=function(album){
            $state.go('main.gallery', { albumid: album.id });
        }

    }]);
    app.controller('albumController', ['$scope', 'albumsService', 'imageService', 'appConfig', 'selectedImage', '$state', 'selectedAlbum', '$rootScope', function ($scope, albumsService, imageService, appConfig, selectedImage, $state, selectedAlbum, $rootScope) {
        var self = this;
        this.currentIndex = 0;
        this.count = 24;
        this.curAlbum = selectedAlbum.album ;

        $rootScope.lastAlbum = selectedAlbum.album;
        var onImageGotten = function (images) {
            if (self.currentIndex === 0 && self.curAlbum.images.length === 0) {
                self.curAlbum.images = images;
                if (self.curAlbum.images.length >= (self.count-1)) {
                    self.curAlbum.images[self.curAlbum.images.length - 1].showPlaceholder = true;
                }
            } else if (self.currentIndex > 0 && self.curAlbum.images.length < (self.currentIndex + self.count-1)) {
                self.curAlbum.images[self.curAlbum.images.length - 1].showPlaceholder = images.length <= 0;
                self.curAlbum.images = self.curAlbum.images.concat(images);
                if (self.curAlbum.images.length === self.currentIndex + self.count) {
                    self.curAlbum.images[self.curAlbum.images.length - 1].showPlaceholder = true;
                }
            }
        }
        this.getAlbumImages = function () {
            imageService.getImagesFromAlbum(self.curAlbum, { start: self.currentIndex, count: self.count }).then(onImageGotten);
        }
        this.showNext = function () {
            this.currentIndex += this.count;
            imageService.getImagesFromAlbum(self.curAlbum, { start: self.currentIndex, count: self.count }).then(onImageGotten)
        }
        this.getImageURL = function (img, size) {
            return imageService.getImageURL(img, size);
        }
        this.onImageSelected = function (image) {
            selectedImage.image = image;
            selectedImage.album = self.curAlbum;
            $state.go('main.singleImage', { imageid: image.id });
        }
       this.getAlbumImages();

       $scope.$on('imageUploaded', function (e, imageId) {
           imageService.getImageById(imageId).then(function (img) {
               self.curAlbum.images.unshift(img[0]);
           });

       });

    }]);
    app.controller('createAlbumController', ['$scope', 'albumsService', '$uibModalInstance', 'authService', 'selectedAlbum', '$rootScope', function ($scope, albumsService, $uibModalInstance, authService, selectedAlbum, $rootScope) {
        var self = this;

        self.postingAlbum = false;
        self.modalTitle = "Create Album";
        var editAlbum = function () {
            self.postingAlbum = true;
            albumsService.updateAlbum(selectedAlbum.album.id, self.currentAlbum.albumName).then(function (res) {
                if (res) {
                    selectedAlbum.album = res;
                }
                $uibModalInstance.close(res);
            }).finally(function () {
                self.postingAlbum = false;
            });
        }
        var createAlbum = function () {
            var auth = authService.currentContext();
            self.postingAlbum = true;
            albumsService.createAlbum(self.currentAlbum.albumName, auth.userId).then(function (res) {
                $uibModalInstance.close(res);
            }).finally(function () {
                self.postingAlbum = false;
            });

        }

        var postFunc = createAlbum;
        if (selectedAlbum.album != null) {
            self.currentAlbum = angular.copy(selectedAlbum.album);
            self.modalTitle = "Edit Album";
            postFunc = editAlbum;
        }
        self.post = function () {
            postFunc();
        }

        self.cancel = function () {
            $uibModalInstance.dismiss('cancel');
        }

        $scope.$on('modal.closing', function (event) {
            if ($scope.uploading) {
                event.preventDefault();
            }
        });

    }]);

    app.controller('deleteAlbumController', ['$scope', 'albumsService', '$uibModalInstance', 'selectedAlbum','$state', function ($scope, albumsService, $uibModalInstance, selectedAlbum,$state) {
        var self = this;
        $scope.albumName = selectedAlbum.album.albumName;
        self.deletingAlbum = false;
        self.deleteAlbum = function () {
            self.deletingAlbum = true;
            albumsService.deleteAlbum(selectedAlbum.album.id).then(function (res) {
                $uibModalInstance.close(res);
                $state.go($state.previous.name);

            }).finally(function () {
                self.deletingAlbum = false;
            });

        }
        self.cancel = function () {
            $uibModalInstance.dismiss('cancel');
        }

        $scope.$on('modal.closing', function (event) {
            if ($scope.uploading) {
                event.preventDefault();
            }
        });

    }]);

    app.controller('deleteimageController', ['$scope', 'imageService', '$uibModalInstance', '$state', '$rootScope','$location',
                                    function ($scope, imageService, $uibModalInstance, $state, $rootScope, $location) {
        var self = this;
        self.currantImageId = $state.params["imageid"];

        self.delete = function () {

            imageService.deleteImage(self.currantImageId).then(function (res) {
                $uibModalInstance.close(res);

                $location.path('/album/' + $rootScope.lastAlbum.id);
                //$state.go('main.gallery', { albumid: $rootScope.lastAlbum.id })
            }).finally(function () {
               //;
            });

            ;
        }

        self.cancel = function () {
            $uibModalInstance.dismiss('cancel');
        }

        $scope.$on('modal.closing', function (event) {
            if ($scope.uploading) {
                event.preventDefault();
            }
        });

    }]);

    app.controller('imageController', ['currentImage', 'imageService', 'authContext','$q',function (currentImage, imageService, authContext,$q) {
        var self = this;
        $q.when(currentImage).then(function (curImage) {
            if (angular.isArray(curImage)){
                self.currentImage = curImage[0];
                self.currentAlbum = curImage[0].album
            }
            else{
                self.currentImage = curImage.image;
                self.currentAlbum = curImage.album;
            }

            self.currentAlbum.owner = authContext.currentUser.email;
        });

        self.getCurrentImageURL = function (size) {
            return imageService.getImageURL(this.currentImage, size);
        }

        self.hasBeenLiked = false;
        self.like = function () {
            if (!self.hasBeenLiked) {
                imageService.likeImage(self.currentImage.id).then(function (res) {
                    self.hasBeenLiked = res;
                });
            }

        }
    }]);
    app.controller('navController', ['$scope', '$uibModal', '$state',function ($scope, $uibModal, $state) {

        $scope.showUpload = false;
        $scope.showCreateAlbum = false;
        $scope.showMenu = true;
        $scope.showDelImage = false;
        $scope.$on('$stateChangeSuccess', function (e, toState) {
            $scope.navCollapsed = true;
            $scope.showUpload = toState.name === 'main.gallery';
            $scope.showDelImage = toState.name === 'main.singleImage';
            $scope.showCreateAlbum = toState.name === 'main.albums';
            $scope.showMenu = toState.name !== 'main.singleImage';
        });

        var openModal = function (options) {
            return $uibModal.open(options);
        }

        this.openUploadModal = function () {

            openModal({
                animation: true,
                templateUrl: 'uploadModal.html',
                controller: 'uploadController',
                controllerAs: 'uploadCtrl'
            }).result.then(function (uplodedFile) {
                console.log('upload modal completed at: ' + new Date());
            }, function () {
                console.log('Modal dismissed at: ' + new Date());
            });

        }
        this.openAlbummModal = function (isEdit) {
            openModal({
                animation: true,
                templateUrl: 'createAlbum.html',
                controller: 'createAlbumController',
                controllerAs: 'crtAlbumCtrl'
            }).result.then(function (createdAlbum) {}, function () {
                console.log('Modal dismissed at: ' + new Date());
            });
        }
        this.deleteAlbumModal = function () {
            openModal({
                animation: true,
                templateUrl: 'deleteAlbum.html',
                controller: 'deleteAlbumController',
                controllerAs: 'delAlbumCtrl'
            }).result.then(function (album) {

                $state.go('main.albums');
            }, function () {
                console.log('Modal dismissed at: ' + new Date());
            });
        }
        this.deleteImageModal = function () {
            openModal({
                animation: true,
                templateUrl: 'deleteImage.html',
                controller: 'deleteimageController',
                controllerAs: 'imgCtrl'
            }).result.then(function (createdAlbum) { }, function () {
                console.log('Modal dismissed at: ' + new Date());
            });
        }

    }]);
    app.controller('titleController', ['$scope', 'selectedAlbum', function ($scope, selectedAlbum) {
        $scope.$on('userAuthenticated', function (e, authContext) {
            $scope.userEmail = authContext.currentUser.email;
        });
        $scope.curAlbum = selectedAlbum;

    }]);
    app.controller('uploadController', ['$scope', 'uploadService', '$uibModalInstance', '$timeout', 'authService', 'selectedAlbum', function ($scope, uploadService, $uibModalInstance, $timeout, authService, selectedAlbum) {

        var init = function () {
            $scope.progress = -1;
            $scope.uploading = false;
            $scope.hasError = false;
            $scope.progressType = "info";
        }

        var uploadOptions = {
            complete: function () {
                $scope.uploading = false;
                $timeout(function () {
                    $uibModalInstance.close($scope.selectedFile);
                }, 1000);

            },
            progress: function (progress) {
                $scope.progress = parseFloat(progress);
            },
            error: function () {
                $scope.uploading = false;
                $scope.hasError = true;
                $scope.progressType = "error";
            },
            userId: authService.currentContext().userId,
            albumId: selectedAlbum.album.id
        }
        this.showProgress = function () {
            return ($scope.progress >= 0);
        }
        this.onFileChange = function (files) {
            $scope.selectedFile = files[0];
        }
        this.upload = function () {
            if (!angular.isUndefined($scope.selectedFile)) {
                $scope.progress = 0;
                uploadService($scope.selectedFile, uploadOptions);
                $scope.uploading = true;
            }
        }
        this.cancel = function () {
            $uibModalInstance.dismiss('cancel');
        }
        this.reset = function () {
            init();
        }
        $scope.$on('modal.closing', function (event) {
            if ($scope.uploading) {
                event.preventDefault();
            }
        });

    }]);
})(angular)<commit_msg>Update controllers.js<commit_after>(function (angular) {
    'use strict';

    var app = angular.module('app');
    app.controller('albumsController', ['$scope', 'albumsService', 'authContext', '$state', function ($scope, albumsService, authContext, $state) {
        var self = this;

        self.albums=[];
        albumsService.getUserAlbums(authContext.userId).then(function (albums) {
            if (albums && angular.isArray(albums)) {
                self.albums = albums;
            }
        });
        $scope.$on('albumCreated', function (e,album) {
            self.albums.push(album);
        });
        self.goToAlbum=function(album){
            $state.go('main.gallery', { albumid: album.id });
        }

    }]);
    app.controller('albumController', ['$scope', 'albumsService', 'imageService', 'appConfig', 'selectedImage', '$state', 'selectedAlbum', '$rootScope', function ($scope, albumsService, imageService, appConfig, selectedImage, $state, selectedAlbum, $rootScope) {
        var self = this;
        this.currentIndex = 0;
        this.count = 24;
        this.curAlbum = selectedAlbum.album ;

        $rootScope.lastAlbum = selectedAlbum.album;
        var onImageGotten = function (images) {
            if (self.currentIndex === 0 && self.curAlbum.images.length === 0) {
                self.curAlbum.images = images;
                if (self.curAlbum.images.length >= (self.count-1)) {
                    self.curAlbum.images[self.curAlbum.images.length - 1].showPlaceholder = true;
                }
            } else if (self.currentIndex > 0 && self.curAlbum.images.length < (self.currentIndex + self.count-1)) {
                self.curAlbum.images[self.curAlbum.images.length - 1].showPlaceholder = images.length <= 0;
                self.curAlbum.images = self.curAlbum.images.concat(images);
                if (self.curAlbum.images.length === self.currentIndex + self.count) {
                    self.curAlbum.images[self.curAlbum.images.length - 1].showPlaceholder = true;
                }
            }
        }
        this.getAlbumImages = function () {
            imageService.getImagesFromAlbum(self.curAlbum, { start: self.currentIndex, count: self.count }).then(onImageGotten);
        }
        this.showNext = function () {
            this.currentIndex += this.count;
            imageService.getImagesFromAlbum(self.curAlbum, { start: self.currentIndex, count: self.count }).then(onImageGotten)
        }
        this.getImageURL = function (img, size) {
            return imageService.getImageURL(img, size);
        }
        this.onImageSelected = function (image) {
            selectedImage.image = image;
            selectedImage.album = self.curAlbum;
            $state.go('main.singleImage', { imageid: image.id });
        }
       this.getAlbumImages();

       $scope.$on('imageUploaded', function (e, imageId) {
           imageService.getImageById(imageId).then(function (img) {
               self.curAlbum.images.unshift(img[0]);
           });

       });

    }]);
    app.controller('createAlbumController', ['$scope', 'albumsService', '$uibModalInstance', 'authService', 'selectedAlbum', '$rootScope', function ($scope, albumsService, $uibModalInstance, authService, selectedAlbum, $rootScope) {
        var self = this;

        self.postingAlbum = false;
        self.modalTitle = "Create Album";
        var editAlbum = function () {
            self.postingAlbum = true;
            albumsService.updateAlbum(selectedAlbum.album.id, self.currentAlbum.albumName).then(function (res) {
                if (res) {
                    selectedAlbum.album = res;
                }
                $uibModalInstance.close(res);
            }).finally(function () {
                self.postingAlbum = false;
            });
        }
        var createAlbum = function () {
            var auth = authService.currentContext();
            self.postingAlbum = true;
            albumsService.createAlbum(self.currentAlbum.albumName, auth.userId).then(function (res) {
                $uibModalInstance.close(res);
            }).finally(function () {
                self.postingAlbum = false;
            });

        }

        var postFunc = createAlbum;
        if (selectedAlbum.album != null) {
            self.currentAlbum = angular.copy(selectedAlbum.album);
            self.modalTitle = "Edit Album";
            postFunc = editAlbum;
        }
        self.post = function () {
            postFunc();
        }

        self.cancel = function () {
            $uibModalInstance.dismiss('cancel');
        }

        $scope.$on('modal.closing', function (event) {
            if ($scope.uploading) {
                event.preventDefault();
            }
        });

    }]);

    app.controller('deleteAlbumController', ['$scope', 'albumsService', '$uibModalInstance', 'selectedAlbum','$state', function ($scope, albumsService, $uibModalInstance, selectedAlbum,$state) {
        var self = this;
        $scope.albumName = selectedAlbum.album.albumName;
        self.deletingAlbum = false;
        self.deleteAlbum = function () {
            self.deletingAlbum = true;
            albumsService.deleteAlbum(selectedAlbum.album.id).then(function (res) {
                $uibModalInstance.close(res);
                $state.go($state.previous.name);

            }).finally(function () {
                self.deletingAlbum = false;
            });

        }
        self.cancel = function () {
            $uibModalInstance.dismiss('cancel');
        }

        $scope.$on('modal.closing', function (event) {
            if ($scope.uploading) {
                event.preventDefault();
            }
        });

    }]);

    app.controller('deleteimageController', ['$scope', 'imageService', '$uibModalInstance', '$state', '$rootScope','$location',
                                    function ($scope, imageService, $uibModalInstance, $state, $rootScope, $location) {
        var self = this;
        self.currantImageId = $state.params["imageid"];

        self.delete = function () {

            imageService.deleteImage(self.currantImageId).then(function (res) {
                $uibModalInstance.close(res);

                $location.path('/album/' + $rootScope.lastAlbum.id);
                //$state.go('main.gallery', { albumid: $rootScope.lastAlbum.id })
            }).finally(function () {
               //;
            });

            ;
        }

        self.cancel = function () {
            $uibModalInstance.dismiss('cancel');
        }

        $scope.$on('modal.closing', function (event) {
            if ($scope.uploading) {
                event.preventDefault();
            }
        });

    }]);

    app.controller('imageController', ['currentImage', 'imageService', 'authContext', '$q', '$scope', function (currentImage, imageService, authContext, $q, $scope) {
        var self = this;
        $q.when(currentImage).then(function (curImage) {
            if (angular.isArray(curImage)){
                self.currentImage = curImage[0];
                self.currentAlbum = curImage[0].album
            }
            else{
                self.currentImage = curImage.image;
                self.currentAlbum = curImage.album;
            }

            self.currentAlbum.owner = authContext.currentUser.email;
        });

        self.getCurrentImageURL = function (size) {
            return imageService.getImageURL(this.currentImage, size);
        }

        self.hasBeenLiked = false;
        self.like = function () {
            if (!self.hasBeenLiked) {
                imageService.likeImage(self.currentImage.id).then(function (res) {
                    self.hasBeenLiked = res;
                });
            }
        }

        $scope.$on('imageDeleted', function (e, imageId) {
            for (var i = 0; i < self.currentAlbum.images.length; i++) {
                if (self.currentAlbum.images[i].id == imageId) {
                    self.currentAlbum.images.splice(i, 1);
                    break;
                }
            }
        });

    }]);
    app.controller('navController', ['$scope', '$uibModal', '$state',function ($scope, $uibModal, $state) {

        $scope.showUpload = false;
        $scope.showCreateAlbum = false;
        $scope.showMenu = true;
        $scope.showDelImage = false;
        $scope.$on('$stateChangeSuccess', function (e, toState) {
            $scope.navCollapsed = true;
            $scope.showUpload = toState.name === 'main.gallery';
            $scope.showDelImage = toState.name === 'main.singleImage';
            $scope.showCreateAlbum = toState.name === 'main.albums';
            $scope.showMenu = toState.name !== 'main.singleImage';
        });

        var openModal = function (options) {
            return $uibModal.open(options);
        }

        this.openUploadModal = function () {

            openModal({
                animation: true,
                templateUrl: 'uploadModal.html',
                controller: 'uploadController',
                controllerAs: 'uploadCtrl'
            }).result.then(function (uplodedFile) {
                console.log('upload modal completed at: ' + new Date());
            }, function () {
                console.log('Modal dismissed at: ' + new Date());
            });

        }
        this.openAlbummModal = function (isEdit) {
            openModal({
                animation: true,
                templateUrl: 'createAlbum.html',
                controller: 'createAlbumController',
                controllerAs: 'crtAlbumCtrl'
            }).result.then(function (createdAlbum) {}, function () {
                console.log('Modal dismissed at: ' + new Date());
            });
        }
        this.deleteAlbumModal = function () {
            openModal({
                animation: true,
                templateUrl: 'deleteAlbum.html',
                controller: 'deleteAlbumController',
                controllerAs: 'delAlbumCtrl'
            }).result.then(function (album) {

                $state.go('main.albums');
            }, function () {
                console.log('Modal dismissed at: ' + new Date());
            });
        }
        this.deleteImageModal = function () {
            openModal({
                animation: true,
                templateUrl: 'deleteImage.html',
                controller: 'deleteimageController',
                controllerAs: 'imgCtrl'
            }).result.then(function (createdAlbum) { }, function () {
                console.log('Modal dismissed at: ' + new Date());
            });
        }

    }]);
    app.controller('titleController', ['$scope', 'selectedAlbum', function ($scope, selectedAlbum) {
        $scope.$on('userAuthenticated', function (e, authContext) {
            $scope.userEmail = authContext.currentUser.email;
        });
        $scope.curAlbum = selectedAlbum;

    }]);
    app.controller('uploadController', ['$scope', 'uploadService', '$uibModalInstance', '$timeout', 'authService', 'selectedAlbum', function ($scope, uploadService, $uibModalInstance, $timeout, authService, selectedAlbum) {

        var init = function () {
            $scope.progress = -1;
            $scope.uploading = false;
            $scope.hasError = false;
            $scope.progressType = "info";
        }

        var uploadOptions = {
            complete: function () {
                $scope.uploading = false;
                $timeout(function () {
                    $uibModalInstance.close($scope.selectedFile);
                }, 1000);

            },
            progress: function (progress) {
                $scope.progress = parseFloat(progress);
            },
            error: function () {
                $scope.uploading = false;
                $scope.hasError = true;
                $scope.progressType = "error";
            },
            userId: authService.currentContext().userId,
            albumId: selectedAlbum.album.id
        }
        this.showProgress = function () {
            return ($scope.progress >= 0);
        }
        this.onFileChange = function (files) {
            $scope.selectedFile = files[0];
        }
        this.upload = function () {
            if (!angular.isUndefined($scope.selectedFile)) {
                $scope.progress = 0;
                uploadService($scope.selectedFile, uploadOptions);
                $scope.uploading = true;
            }
        }
        this.cancel = function () {
            $uibModalInstance.dismiss('cancel');
        }
        this.reset = function () {
            init();
        }
        $scope.$on('modal.closing', function (event) {
            if ($scope.uploading) {
                event.preventDefault();
            }
        });

    }]);
})(angular)
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var watchify = require('watchify');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var sourcemaps = require('gulp-sourcemaps');
var gutil = require('gulp-util');
var exit = require('gulp-exit');
var rev = require('gulp-rev');
var revReplace = require('gulp-rev-replace');
var notifier = require('node-notifier');
var rename = require('gulp-rename');

////////////////////////////////////////////////////////////////////////////////
//--------------------------- Variables --------------------------------------//
//----------------------------------------------------------------------------//

// The package.json
var pkg;

////////////////////////////////////////////////////////////////////////////////
//------------------------- Helper functions ---------------------------------//
//----------------------------------------------------------------------------//

function readPackage () {
  pkg = JSON.parse(fs.readFileSync('package.json'));
}
readPackage();

////////////////////////////////////////////////////////////////////////////////
//------------------------- Callable tasks -----------------------------------//
//----------------------------------------------------------------------------//

gulp.task('default', ['clean'], function () {
  gulp.start('build');
});

gulp.task('serve', ['vendorScripts', 'javascript', 'styles', 'fonts'], function () {
  browserSync({
    port: 3000,
    server: {
      baseDir: ['.tmp', 'app'],
      routes: {
        '/node_modules': './node_modules'
      }
    }
  });

  // watch for changes
  gulp.watch([
    'app/*.html',
    'app/assets/graphics/**/*',
    '.tmp/assets/fonts/**/*'
  ]).on('change', reload);

  gulp.watch('app/assets/styles/**/*.scss', ['styles']);
  gulp.watch('app/assets/fonts/**/*', ['fonts']);
  gulp.watch('package.json', ['vendorScripts']);
});

gulp.task('clean', require('del').bind(null, ['.tmp', 'dist']));

gulp.task('build', ['vendorScripts', 'javascript'], function () {
  gulp.start(['html', 'images', 'fonts', 'extras'], function () {
    return gulp.src('dist/**/*')
      .pipe($.size({title: 'build', gzip: true}))
      .pipe(exit());
  });
});

////////////////////////////////////////////////////////////////////////////////
//------------------------- Browserify tasks ---------------------------------//
//------------------- (Not to be called directly) ----------------------------//
//----------------------------------------------------------------------------//

// Compiles the user's script files to bundle.js.
// When including the file in the index.html we need to refer to bundle.js not
// main.js
gulp.task('javascript', function () {
  // set the correct environment, which controls what happens in config.js
  if (!process.env.DS_ENV) {
    if (!process.env.TRAVIS_BRANCH
    || process.env.TRAVIS_BRANCH !== process.env.DEPLOY_BRANCH) {
      process.env.DS_ENV = 'production';
    } else {
      process.env.DS_ENV = 'staging';
    }
  }

  var watcher = watchify(browserify({
    entries: ['./app/assets/scripts/main.js'],
    debug: true,
    cache: {},
    packageCache: {},
    fullPaths: true
  }));

  function bundler () {
    if (pkg.dependencies) {
      watcher.external(Object.keys(pkg.dependencies));
    }
    return watcher.bundle()
      .on('error', function (e) {
        notifier.notify({
          title: 'Oops! Browserify errored:',
          message: e.message
        });
        console.log('Sass error:', e);
        // Allows the watch to continue.
        this.emit('end');
      })
      .pipe(source('bundle.js'))
      .pipe(buffer())
      // Source maps.
      .pipe(sourcemaps.init({loadMaps: true}))
      .pipe(sourcemaps.write('./'))
      .pipe(gulp.dest('.tmp/assets/scripts'))
      .pipe(reload({stream: true}));
  }

  watcher
  .on('log', gutil.log)
  .on('update', bundler);

  return bundler();
});

// Vendor scripts. Basically all the dependencies in the package.js.
// Therefore be careful and keep the dependencies clean.
gulp.task('vendorScripts', function() {
  // Ensure package is updated.
  readPackage();
  var vb = browserify({
    debug: true,
    require: pkg.dependencies ? Object.keys(pkg.dependencies) : []
  });
  return vb.bundle()
    .on('error', gutil.log.bind(gutil, 'Browserify Error'))
    .pipe(source('vendor.js'))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: true}))
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest('.tmp/assets/scripts/'))
    .pipe(reload({stream: true}));
});

////////////////////////////////////////////////////////////////////////////////
//--------------------------- Helper tasks -----------------------------------//
//----------------------------------------------------------------------------//

gulp.task('styles', function () {
  return gulp.src('app/assets/styles/main.scss')
    .pipe($.plumber(function (e) {
      notifier.notify({
        title: 'Oops! Sass errored:',
        message: e.message
      });
      console.log('Sass error:', e.toString());
      // Allows the watch to continue.
      this.emit('end');
    }))
    .pipe($.sourcemaps.init())
    .pipe($.sass({
      outputStyle: 'nested', // libsass doesn't support expanded yet
      precision: 10,
      includePaths: ['.']
      .concat(require('node-bourbon').includePaths)
      .concat(require('node-neat').includePaths)
    }))
    // Power to the user. Sass provides enough mixins to handle prefix.
    /*.pipe($.postcss([
      require('autoprefixer-core')({browsers: ['last 1 version']})
    ]))*/
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest('.tmp/assets/styles'))
    .pipe(reload({stream: true}));
});

gulp.task('html', ['styles'], function () {
  var assets = $.useref.assets({searchPath: ['.tmp', 'app', '.']});

  return gulp.src('app/*.html')
    .pipe(assets)
    // .pipe($.if('*.js', $.uglify())) // TODO: Fix this, seems to be broken with React
    .pipe($.if('*.css', $.csso()))
    .pipe(rev())
    .pipe(assets.restore())
    .pipe($.useref())
    .pipe(revReplace())
    //.pipe($.if('*.html', $.minifyHtml({conditionals: true, loose: true})))
    .pipe(gulp.dest('dist'));
});

gulp.task('images', function () {
  return gulp.src('app/assets/graphics/**/*')
    .pipe($.cache($.imagemin({
      progressive: true,
      interlaced: true,
      // don't remove IDs from SVGs, they are often used
      // as hooks for embedding and styling
      svgoPlugins: [{cleanupIDs: false}]
    })))
    .pipe(gulp.dest('dist/assets/graphics'));
});

gulp.task('fonts', function () {
  return gulp.src('app/assets/fonts/**/*')
    .pipe(gulp.dest('.tmp/assets/fonts'))
    .pipe(gulp.dest('dist/assets/fonts'));
});

gulp.task('extras', function () {
  return gulp.src([
    'app/**/*',
    '!app/*.html',
    '!app/assets/graphics/**',
    '!app/assets/vendor/**',
    '!app/assets/styles/**',
    '!app/assets/scripts/**'
  ], {
    dot: true
  }).pipe(gulp.dest('dist'));
});
<commit_msg>hotfix env issue<commit_after>'use strict';

var fs = require('fs');
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var watchify = require('watchify');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var sourcemaps = require('gulp-sourcemaps');
var gutil = require('gulp-util');
var exit = require('gulp-exit');
var rev = require('gulp-rev');
var revReplace = require('gulp-rev-replace');
var notifier = require('node-notifier');
var rename = require('gulp-rename');

////////////////////////////////////////////////////////////////////////////////
//--------------------------- Variables --------------------------------------//
//----------------------------------------------------------------------------//

// The package.json
var pkg;

////////////////////////////////////////////////////////////////////////////////
//------------------------- Helper functions ---------------------------------//
//----------------------------------------------------------------------------//

function readPackage () {
  pkg = JSON.parse(fs.readFileSync('package.json'));
}
readPackage();

////////////////////////////////////////////////////////////////////////////////
//------------------------- Callable tasks -----------------------------------//
//----------------------------------------------------------------------------//

gulp.task('default', ['clean'], function () {
  gulp.start('build');
});

gulp.task('serve', ['vendorScripts', 'javascript', 'styles', 'fonts'], function () {
  browserSync({
    port: 3000,
    server: {
      baseDir: ['.tmp', 'app'],
      routes: {
        '/node_modules': './node_modules'
      }
    }
  });

  // watch for changes
  gulp.watch([
    'app/*.html',
    'app/assets/graphics/**/*',
    '.tmp/assets/fonts/**/*'
  ]).on('change', reload);

  gulp.watch('app/assets/styles/**/*.scss', ['styles']);
  gulp.watch('app/assets/fonts/**/*', ['fonts']);
  gulp.watch('package.json', ['vendorScripts']);
});

gulp.task('clean', require('del').bind(null, ['.tmp', 'dist']));

gulp.task('build', ['vendorScripts', 'javascript'], function () {
  gulp.start(['html', 'images', 'fonts', 'extras'], function () {
    return gulp.src('dist/**/*')
      .pipe($.size({title: 'build', gzip: true}))
      .pipe(exit());
  });
});

////////////////////////////////////////////////////////////////////////////////
//------------------------- Browserify tasks ---------------------------------//
//------------------- (Not to be called directly) ----------------------------//
//----------------------------------------------------------------------------//

// Compiles the user's script files to bundle.js.
// When including the file in the index.html we need to refer to bundle.js not
// main.js
gulp.task('javascript', function () {
  // set the correct environment, which controls what happens in config.js
  if (!process.env.DS_ENV) {
    if (!process.env.TRAVIS_BRANCH ||
      process.env.TRAVIS_BRANCH !== process.env.PRODUCTION_BRANCH) {
      process.env.DS_ENV = 'staging';
    } else {
      process.env.DS_ENV = 'production';
    }
  }

  var watcher = watchify(browserify({
    entries: ['./app/assets/scripts/main.js'],
    debug: true,
    cache: {},
    packageCache: {},
    fullPaths: true
  }));

  function bundler () {
    if (pkg.dependencies) {
      watcher.external(Object.keys(pkg.dependencies));
    }
    return watcher.bundle()
      .on('error', function (e) {
        notifier.notify({
          title: 'Oops! Browserify errored:',
          message: e.message
        });
        console.log('Sass error:', e);
        // Allows the watch to continue.
        this.emit('end');
      })
      .pipe(source('bundle.js'))
      .pipe(buffer())
      // Source maps.
      .pipe(sourcemaps.init({loadMaps: true}))
      .pipe(sourcemaps.write('./'))
      .pipe(gulp.dest('.tmp/assets/scripts'))
      .pipe(reload({stream: true}));
  }

  watcher
  .on('log', gutil.log)
  .on('update', bundler);

  return bundler();
});

// Vendor scripts. Basically all the dependencies in the package.js.
// Therefore be careful and keep the dependencies clean.
gulp.task('vendorScripts', function() {
  // Ensure package is updated.
  readPackage();
  var vb = browserify({
    debug: true,
    require: pkg.dependencies ? Object.keys(pkg.dependencies) : []
  });
  return vb.bundle()
    .on('error', gutil.log.bind(gutil, 'Browserify Error'))
    .pipe(source('vendor.js'))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: true}))
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest('.tmp/assets/scripts/'))
    .pipe(reload({stream: true}));
});

////////////////////////////////////////////////////////////////////////////////
//--------------------------- Helper tasks -----------------------------------//
//----------------------------------------------------------------------------//

gulp.task('styles', function () {
  return gulp.src('app/assets/styles/main.scss')
    .pipe($.plumber(function (e) {
      notifier.notify({
        title: 'Oops! Sass errored:',
        message: e.message
      });
      console.log('Sass error:', e.toString());
      // Allows the watch to continue.
      this.emit('end');
    }))
    .pipe($.sourcemaps.init())
    .pipe($.sass({
      outputStyle: 'nested', // libsass doesn't support expanded yet
      precision: 10,
      includePaths: ['.']
      .concat(require('node-bourbon').includePaths)
      .concat(require('node-neat').includePaths)
    }))
    // Power to the user. Sass provides enough mixins to handle prefix.
    /*.pipe($.postcss([
      require('autoprefixer-core')({browsers: ['last 1 version']})
    ]))*/
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest('.tmp/assets/styles'))
    .pipe(reload({stream: true}));
});

gulp.task('html', ['styles'], function () {
  var assets = $.useref.assets({searchPath: ['.tmp', 'app', '.']});

  return gulp.src('app/*.html')
    .pipe(assets)
    // .pipe($.if('*.js', $.uglify())) // TODO: Fix this, seems to be broken with React
    .pipe($.if('*.css', $.csso()))
    .pipe(rev())
    .pipe(assets.restore())
    .pipe($.useref())
    .pipe(revReplace())
    //.pipe($.if('*.html', $.minifyHtml({conditionals: true, loose: true})))
    .pipe(gulp.dest('dist'));
});

gulp.task('images', function () {
  return gulp.src('app/assets/graphics/**/*')
    .pipe($.cache($.imagemin({
      progressive: true,
      interlaced: true,
      // don't remove IDs from SVGs, they are often used
      // as hooks for embedding and styling
      svgoPlugins: [{cleanupIDs: false}]
    })))
    .pipe(gulp.dest('dist/assets/graphics'));
});

gulp.task('fonts', function () {
  return gulp.src('app/assets/fonts/**/*')
    .pipe(gulp.dest('.tmp/assets/fonts'))
    .pipe(gulp.dest('dist/assets/fonts'));
});

gulp.task('extras', function () {
  return gulp.src([
    'app/**/*',
    '!app/*.html',
    '!app/assets/graphics/**',
    '!app/assets/vendor/**',
    '!app/assets/styles/**',
    '!app/assets/scripts/**'
  ], {
    dot: true
  }).pipe(gulp.dest('dist'));
});
<|endoftext|>


<commit_before>import { addClass } from "../dom/DOMUtil"
import { I18NMixins } from "../language/I18NMixins";
import Events from "../core/Events";
import { DOMMixins } from "../dom/DOMMixins";
import { classMixin, mergeData, trim } from "../core/Util"
import * as DOM from "../dom/DOM"
import { Animate } from "../animation/Animate"
import { easeInSpline } from "../animation/Ease"
import * as Browser from "../core/Browser"
import { lookupMediaType } from "../media/MediaType";
import { Text } from "../media/Media"

export class Slide {

    constructor(data, options, title_slide, language) {
        if (language) {
            this.setLanguage(language)
        }

        // DOM Elements
        this._el = {
            container: {},
            scroll_container: {},
            background: {},
            content_container: {},
            content: {}
        };

        // Components
        this._media = null;
        this._mediaclass = {};
        this._text = {};
        this._background_media = null;

        // State
        this._state = {
            loaded: false
        };

        this.has = {
            headline: false,
            text: false,
            media: false,
            title: false,
            background: {
                image: false,
                color: false,
                color_value: ""
            }
        }

        this.has.title = title_slide;

        // Data
        this.data = {
            unique_id: null,
            background: null,
            start_date: null,
            end_date: null,
            location: null,
            text: null,
            media: null,
            autolink: true
        };

        // Options
        this.options = {
            // animation
            duration: 1000,
            slide_padding_lr: 40,
            ease: easeInSpline,
            width: 600,
            height: 600,
            skinny_size: 650,
            media_name: ""
        };

        // Actively Displaying
        this.active = false;

        // Animation Object
        this.animator = {};

        // Merge Data and Options
        mergeData(this.options, options);
        mergeData(this.data, data);

        this._initLayout();
        this._initEvents();

    }

    /*	Adding, Hiding, Showing etc
    ================================================== */
    show() {
        this.animator = Animate(this._el.slider_container, {
            left: -(this._el.container.offsetWidth * n) + "px",
            duration: this.options.duration,
            easing: this.options.ease
        });
    }

    hide() {

    }

    setActive(is_active) {
        this.active = is_active;

        if (this.active) {
            if (this.data.background) {
                this.fire("background_change", this.has.background);
            }
            this.loadMedia();
        } else {
            this.stopMedia();
        }
    }

    addTo(container) {
        container.appendChild(this._el.container);
        //this.onAdd();
    }

    removeFrom(container) {
        container.removeChild(this._el.container);
    }

    updateDisplay(width, height, layout) {
        var content_width,
            content_padding_left = this.options.slide_padding_lr,
            content_padding_right = this.options.slide_padding_lr;

        if (width) {
            this.options.width = width;
        } else {
            this.options.width = this._el.container.offsetWidth;
        }

        content_width = this.options.width - (this.options.slide_padding_lr * 2);

        if (Browser.mobile && (this.options.width <= this.options.skinny_size)) {
            content_padding_left = 0;
            content_padding_right = 0;
            content_width = this.options.width;
        } else if (layout == "landscape") {

        } else if (this.options.width <= this.options.skinny_size) {
            content_padding_left = 50;
            content_padding_right = 50;
            content_width = this.options.width - content_padding_left - content_padding_right;
        } else {

        }

        this._el.content.style.paddingLeft = content_padding_left + "px";
        this._el.content.style.paddingRight = content_padding_right + "px";
        this._el.content.style.width = content_width + "px";

        if (height) {
            this.options.height = height;
            //this._el.scroll_container.style.height		= this.options.height + "px";

        } else {
            this.options.height = this._el.container.offsetHeight;
        }

        if (this._media) {

            if (!this.has.text && this.has.headline) {
                this._media.updateDisplay(content_width, (this.options.height - this._text.headlineHeight()), layout);
            } else if (!this.has.text && !this.has.headline) {
                this._media.updateDisplay(content_width, this.options.height, layout);
            } else if (this.options.width <= this.options.skinny_size) {
                this._media.updateDisplay(content_width, this.options.height, layout);
            } else {
                this._media.updateDisplay(content_width / 2, this.options.height, layout);
            }
        }

        this._updateBackgroundDisplay();
    }

    loadMedia() {
        var self = this;

        if (this._media && !this._state.loaded) {
            this._media.loadMedia();
            this._state.loaded = true;
        }

        if (this._background_media && !this._background_media._state.loaded) {
            this._background_media.on("loaded", function() {
                self._updateBackgroundDisplay();
            });
            this._background_media.loadMedia();
        }
    }

    stopMedia() {
        if (this._media && this._state.loaded) {
            this._media.stopMedia();
        }
    }

    getBackground() {
        return this.has.background;
    }

    scrollToTop() {
        this._el.container.scrollTop = 0;
    }

    getFormattedDate() {

        if (trim(this.data.display_date).length > 0) {
            return this.data.display_date;
        }
        var date_text = "";

        if (!this.has.title) {
            if (this.data.end_date) {
                date_text = " — " + this.data.end_date.getDisplayDate(this.getLanguage());
            }
            if (this.data.start_date) {
                date_text = this.data.start_date.getDisplayDate(this.getLanguage()) + date_text;
            }
        }
        return date_text;
    }

    /*	Events
    ================================================== */

    /*	Private Methods
    ================================================== */
    _initLayout() {
        // Create Layout
        this._el.container = DOM.create("div", "tl-slide");

        if (this.has.title) {
            this._el.container.className = "tl-slide tl-slide-titleslide";
        }

        if (this.data.unique_id) {
            this._el.container.id = this.data.unique_id;
        }
        this._el.scroll_container = DOM.create("div", "tl-slide-scrollable-container", this._el.container);
        this._el.content_container = DOM.create("div", "tl-slide-content-container", this._el.scroll_container);
        this._el.content = DOM.create("div", "tl-slide-content", this._el.content_container);
        this._el.background = DOM.create("div", "tl-slide-background", this._el.container);
        // Style Slide Background
        if (this.data.background) {
            if (this.data.background.url) {
                var media_type = lookupMediaType(this.data.background, true);
                if (media_type) {
                    this._background_media = new media_type.cls(this.data.background, { background: 1 });

                    this.has.background.image = true;
                    this._el.container.className += ' tl-full-image-background';
                    this.has.background.color_value = "#000";
                    this._el.background.style.display = "block";
                }
            }
            if (this.data.background.color) {
                this.has.background.color = true;
                this._el.container.className += ' tl-full-color-background';
                this.has.background.color_value = this.data.background.color;
                //this._el.container.style.backgroundColor = this.data.background.color;
                //this._el.background.style.backgroundColor 	= this.data.background.color;
                //this._el.background.style.display 			= "block";
            }
            if (this.data.background.text_background) {
                this._el.container.className += ' tl-text-background';
            }

        }

        // Determine Assets for layout and loading
        if (this.data.media && this.data.media.url && this.data.media.url != "") {
            this.has.media = true;
        }
        if (this.data.text && this.data.text.text) {
            this.has.text = true;
        }
        if (this.data.text && this.data.text.headline) {
            this.has.headline = true;
        }

        // Create Media
        if (this.has.media) {
            // Determine the media type
            this.data.media.mediatype = lookupMediaType(this.data.media);
            this.options.media_name = this.data.media.mediatype.name;
            this.options.media_type = this.data.media.mediatype.type;
            this.options.autolink = this.data.autolink;

            // Create a media object using the matched class name
            this._media = new this.data.media.mediatype.cls(this.data.media, this.options, this.getLanguage());
        }

        // Create Text
        if (this.has.text || this.has.headline) {
            this._text = new Text(this.data.text, { title: this.has.title, language: this.options.language, autolink: this.data.autolink });
            this._text.addDateText(this.getFormattedDate());
        }

        // Add to DOM
        if (!this.has.text && !this.has.headline && this.has.media) {
            addClass(this._el.container, 'tl-slide-media-only');
            this._media.addTo(this._el.content);
        } else if (this.has.headline && this.has.media && !this.has.text) {
            addClass(this._el.container, 'tl-slide-media-only');
            this._text.addTo(this._el.content);
            this._media.addTo(this._el.content);
        } else if (this.has.text && this.has.media) {
            this._media.addTo(this._el.content);
            this._text.addTo(this._el.content);
        } else if (this.has.text || this.has.headline) {
            addClass(this._el.container, 'tl-slide-text-only');
            this._text.addTo(this._el.content);
        }

        // Fire event that the slide is loaded
        this.onLoaded();

    }

    _initEvents() {

    }

    _updateBackgroundDisplay() {
        if (this._background_media && this._background_media._state.loaded) {
            this._el.background.style.backgroundImage = "url('" + this._background_media.getImageURL(this.options.width, this.options.height) + "')";
        }
    }

}
classMixin(Slide, I18NMixins, Events, DOMMixins)<commit_msg>Disabled of the interactions for non-visible slides<commit_after>import "wicg-inert";

import { addClass } from "../dom/DOMUtil"
import { I18NMixins } from "../language/I18NMixins";
import Events from "../core/Events";
import { DOMMixins } from "../dom/DOMMixins";
import { classMixin, mergeData, trim } from "../core/Util"
import * as DOM from "../dom/DOM"
import { Animate } from "../animation/Animate"
import { easeInSpline } from "../animation/Ease"
import * as Browser from "../core/Browser"
import { lookupMediaType } from "../media/MediaType";
import { Text } from "../media/Media"

export class Slide {

    constructor(data, options, title_slide, language) {
        if (language) {
            this.setLanguage(language)
        }

        // DOM Elements
        this._el = {
            container: {},
            scroll_container: {},
            background: {},
            content_container: {},
            content: {}
        };

        // Components
        this._media = null;
        this._mediaclass = {};
        this._text = {};
        this._background_media = null;

        // State
        this._state = {
            loaded: false
        };

        this.has = {
            headline: false,
            text: false,
            media: false,
            title: false,
            background: {
                image: false,
                color: false,
                color_value: ""
            }
        }

        this.has.title = title_slide;

        // Data
        this.data = {
            unique_id: null,
            background: null,
            start_date: null,
            end_date: null,
            location: null,
            text: null,
            media: null,
            autolink: true
        };

        // Options
        this.options = {
            // animation
            duration: 1000,
            slide_padding_lr: 40,
            ease: easeInSpline,
            width: 600,
            height: 600,
            skinny_size: 650,
            media_name: ""
        };

        // Actively Displaying
        this.active = false;

        // Animation Object
        this.animator = {};

        // Merge Data and Options
        mergeData(this.options, options);
        mergeData(this.data, data);

        this._initLayout();
        this._initEvents();

    }

    /*	Adding, Hiding, Showing etc
    ================================================== */
    show() {
        this.animator = Animate(this._el.slider_container, {
            left: -(this._el.container.offsetWidth * n) + "px",
            duration: this.options.duration,
            easing: this.options.ease
        });
    }

    hide() {

    }

    setActive(is_active) {
        this.active = is_active;

        if (this.active) {
            if (this.data.background) {
                this.fire("background_change", this.has.background);
            }
            this._setInteractive(true)
            this.loadMedia();
        } else {
            this.stopMedia();
            this._setInteractive(false)
        }
    }

    addTo(container) {
        container.appendChild(this._el.container);
        //this.onAdd();
    }

    removeFrom(container) {
        container.removeChild(this._el.container);
    }

    updateDisplay(width, height, layout) {
        var content_width,
            content_padding_left = this.options.slide_padding_lr,
            content_padding_right = this.options.slide_padding_lr;

        if (width) {
            this.options.width = width;
        } else {
            this.options.width = this._el.container.offsetWidth;
        }

        content_width = this.options.width - (this.options.slide_padding_lr * 2);

        if (Browser.mobile && (this.options.width <= this.options.skinny_size)) {
            content_padding_left = 0;
            content_padding_right = 0;
            content_width = this.options.width;
        } else if (layout == "landscape") {

        } else if (this.options.width <= this.options.skinny_size) {
            content_padding_left = 50;
            content_padding_right = 50;
            content_width = this.options.width - content_padding_left - content_padding_right;
        } else {

        }

        this._el.content.style.paddingLeft = content_padding_left + "px";
        this._el.content.style.paddingRight = content_padding_right + "px";
        this._el.content.style.width = content_width + "px";

        if (height) {
            this.options.height = height;
            //this._el.scroll_container.style.height		= this.options.height + "px";

        } else {
            this.options.height = this._el.container.offsetHeight;
        }

        if (this._media) {

            if (!this.has.text && this.has.headline) {
                this._media.updateDisplay(content_width, (this.options.height - this._text.headlineHeight()), layout);
            } else if (!this.has.text && !this.has.headline) {
                this._media.updateDisplay(content_width, this.options.height, layout);
            } else if (this.options.width <= this.options.skinny_size) {
                this._media.updateDisplay(content_width, this.options.height, layout);
            } else {
                this._media.updateDisplay(content_width / 2, this.options.height, layout);
            }
        }

        this._updateBackgroundDisplay();
    }

    loadMedia() {
        var self = this;

        if (this._media && !this._state.loaded) {
            this._media.loadMedia();
            this._state.loaded = true;
        }

        if (this._background_media && !this._background_media._state.loaded) {
            this._background_media.on("loaded", function() {
                self._updateBackgroundDisplay();
            });
            this._background_media.loadMedia();
        }
    }

    stopMedia() {
        if (this._media && this._state.loaded) {
            this._media.stopMedia();
        }
    }

    getBackground() {
        return this.has.background;
    }

    scrollToTop() {
        this._el.container.scrollTop = 0;
    }

    getFormattedDate() {

        if (trim(this.data.display_date).length > 0) {
            return this.data.display_date;
        }
        var date_text = "";

        if (!this.has.title) {
            if (this.data.end_date) {
                date_text = " — " + this.data.end_date.getDisplayDate(this.getLanguage());
            }
            if (this.data.start_date) {
                date_text = this.data.start_date.getDisplayDate(this.getLanguage()) + date_text;
            }
        }
        return date_text;
    }

    /*	Events
    ================================================== */

    /*	Private Methods
    ================================================== */
    _initLayout() {
        // Create Layout
        this._el.container = DOM.create("div", "tl-slide");

        if (this.has.title) {
            this._el.container.className = "tl-slide tl-slide-titleslide";
        }

        if (this.data.unique_id) {
            this._el.container.id = this.data.unique_id;
        }
        this._el.scroll_container = DOM.create("div", "tl-slide-scrollable-container", this._el.container);
        this._el.content_container = DOM.create("div", "tl-slide-content-container", this._el.scroll_container);
        this._el.content = DOM.create("div", "tl-slide-content", this._el.content_container);
        this._el.background = DOM.create("div", "tl-slide-background", this._el.container);
        // Style Slide Background
        if (this.data.background) {
            if (this.data.background.url) {
                var media_type = lookupMediaType(this.data.background, true);
                if (media_type) {
                    this._background_media = new media_type.cls(this.data.background, { background: 1 });

                    this.has.background.image = true;
                    this._el.container.className += ' tl-full-image-background';
                    this.has.background.color_value = "#000";
                    this._el.background.style.display = "block";
                }
            }
            if (this.data.background.color) {
                this.has.background.color = true;
                this._el.container.className += ' tl-full-color-background';
                this.has.background.color_value = this.data.background.color;
                //this._el.container.style.backgroundColor = this.data.background.color;
                //this._el.background.style.backgroundColor 	= this.data.background.color;
                //this._el.background.style.display 			= "block";
            }
            if (this.data.background.text_background) {
                this._el.container.className += ' tl-text-background';
            }

        }

        // Determine Assets for layout and loading
        if (this.data.media && this.data.media.url && this.data.media.url != "") {
            this.has.media = true;
        }
        if (this.data.text && this.data.text.text) {
            this.has.text = true;
        }
        if (this.data.text && this.data.text.headline) {
            this.has.headline = true;
        }

        // Create Media
        if (this.has.media) {
            // Determine the media type
            this.data.media.mediatype = lookupMediaType(this.data.media);
            this.options.media_name = this.data.media.mediatype.name;
            this.options.media_type = this.data.media.mediatype.type;
            this.options.autolink = this.data.autolink;

            // Create a media object using the matched class name
            this._media = new this.data.media.mediatype.cls(this.data.media, this.options, this.getLanguage());
        }

        // Create Text
        if (this.has.text || this.has.headline) {
            this._text = new Text(this.data.text, { title: this.has.title, language: this.options.language, autolink: this.data.autolink });
            this._text.addDateText(this.getFormattedDate());
        }

        // Add to DOM
        if (!this.has.text && !this.has.headline && this.has.media) {
            addClass(this._el.container, 'tl-slide-media-only');
            this._media.addTo(this._el.content);
        } else if (this.has.headline && this.has.media && !this.has.text) {
            addClass(this._el.container, 'tl-slide-media-only');
            this._text.addTo(this._el.content);
            this._media.addTo(this._el.content);
        } else if (this.has.text && this.has.media) {
            this._media.addTo(this._el.content);
            this._text.addTo(this._el.content);
        } else if (this.has.text || this.has.headline) {
            addClass(this._el.container, 'tl-slide-text-only');
            this._text.addTo(this._el.content);
        }

        // Fire event that the slide is loaded
        this.onLoaded();

    }

    _initEvents() {

    }

    _updateBackgroundDisplay() {
        if (this._background_media && this._background_media._state.loaded) {
            this._el.background.style.backgroundImage = "url('" + this._background_media.getImageURL(this.options.width, this.options.height) + "')";
        }
    }

    _setInteractive(is_interactive) {
        if (is_interactive) {
            this._el.container.removeAttribute('inert');
        } else {
            this._el.container.setAttribute('inert', true);
        }
    }
}
classMixin(Slide, I18NMixins, Events, DOMMixins)
<|endoftext|>


<commit_before>(function($){
    $.fn.disableSelection = function() {
        return this
                 .attr('unselectable', 'on')
                 .css('user-select', 'none')
                 .on('selectstart', false);
    };
})(jQuery);

$(document).ready(function () {
	var canvas = $('canvas')[0],
		ctx = canvas.getContext('2d'),
		height = window.innerHeight - 40,
		width = window.innerWidth,
		plane = new Image(),
		tree = new Image(),
		time_interval = 30,
		troopers = [],
		arms_up = true,
		acceleration = 0.0001,
		level = 0,
		running = true,
		troopers_left = 5,
		hits = 0,

		island = {
			radius: 40,
			x: width / 2 - 60,
			y: height + 24
		},

		levels = [
		{
			island_width: 100,
			island_offset: 0,
			goal: 2,
			troopers_left: 5
		},
		{
			island_width: 100,
			island_offset: 0,
			goal: 2,
			troopers_left: 5
		},
		{
			island_width: 80,
			island_offset: 120,
			goal: 3,
			troopers_left: 5
		},
		{
			island_width: 80,
			island_offset: 200,
			goal: 5,
			troopers_left: 8
		},
		{
			island_width: 20,
			island_offset: 0,
			goal: 4,
			troopers_left: 8
		},
		{
			island_width: 100,
			island_offset: 200,
			goal: 3,
			troopers_left: 3
		},
		{
			island_width: 70,
			island_offset: 0,
			goal: 6,
			troopers_left: 8
		},
		{
			island_width: 50,
			island_offset: 150,
			goal: 6,
			troopers_left: 8
		},
		{
			island_width: 30,
			island_offset: 50,
			goal: 3,
			troopers_left: 5
		},
		{
			island_width: 20,
			island_offset: 250,
			goal: 4,
			troopers_left: 5
		},
		{
			island_width: 10,
			island_offset: 0,
			goal: 5,
			troopers_left: 5
		}
		];

	canvas.height = height;
	canvas.width = width;

	plane.horizontal = -200;
	plane.vertical = 50;
	plane.v0x = 0.1;

	plane.onload = function () {
		paintScreen();
	};

	plane.src = 'images/plane.png';
	tree.src = 'images/tree.png';

	function paintScreen() {
		checkTroopers();

		ctx.clearRect(0, 0, width, height);
		drawPlane();
		drawTroopers();
		drawIsland();
		evolvePlane();
		evolveTroopers();

		setTimeout(paintScreen, time_interval);
	};

	function drawPlane() {
		ctx.drawImage(plane, plane.horizontal, plane.vertical);
	};

	function evolvePlane() {
		plane.horizontal += plane.v0x*time_interval;

		if (plane.horizontal > width) {
			plane.horizontal = -200;
		}
	};

	function drawIsland() {
		var x_pos = island.x + levels[level].island_offset,
			island_width = levels[level].island_width;
		ctx.fillStyle = '#e88d15';
		ctx.beginPath();
		ctx.arc(x_pos, island.y, island.radius, 1.2 * Math.PI, 1.5 * Math.PI);
		ctx.lineTo(x_pos + island_width, island.y - island.radius);
		ctx.arc(x_pos + island_width, island.y, island.radius, 1.5 * Math.PI, 1.8 * Math.PI);
		ctx.closePath();
		ctx.fill();

		ctx.drawImage(tree, x_pos + island_width - 35, island.y - 155);
	}

	function Trooper(x, y, v0x, v0y) {
		this.x = x;
		this.y = y;
		this.x0 = x;
		this.y0 = y;
		this.v0x = v0x;
		this.v0y = v0y;
		this.time = 0;
	};

	function drawTroopers() {
		_.each(troopers, function (trooper) {
			ctx.fillStyle = '#11240e';
			ctx.beginPath();
			ctx.arc(trooper.x, trooper.y, 4, 0.5 * Math.PI, 2.5 * Math.PI);
			ctx.fill();
			ctx.lineWidth = 1.5;
			ctx.lineTo(trooper.x, trooper.y + 13);
			ctx.lineTo(trooper.x - 4, trooper.y + 25);
			ctx.moveTo(trooper.x, trooper.y + 13);
			ctx.lineTo(trooper.x + 4, trooper.y + 25);
			if (arms_up) {
				ctx.moveTo(trooper.x, trooper.y + 8);
				ctx.lineTo(trooper.x + 8, trooper.y + 7);
				ctx.moveTo(trooper.x, trooper.y + 8);
				ctx.lineTo(trooper.x - 8, trooper.y + 7);
			} else {
				ctx.moveTo(trooper.x, trooper.y + 8);
				ctx.lineTo(trooper.x + 7, trooper.y + 14);
				ctx.moveTo(trooper.x, trooper.y + 8);
				ctx.lineTo(trooper.x - 7, trooper.y + 14);
			}
			ctx.strokeStyle = '#11240e';
			ctx.stroke();
			ctx.closePath();
		});
	};

	function evolveTroopers() {
		_.each(troopers, function (trooper) {
			trooper.x = trooper.x0 + trooper.v0x * trooper.time;
			trooper.y = trooper.y0 + 0.5 * acceleration * Math.pow(trooper.time, 2);
			trooper.time += time_interval;
		});
	};

	function checkTroopers() {
		_.each(troopers, function (trooper) {
			if (trooper.y > height + 20) {
				troopers.splice(trooper, 1);
			}
			if (trooper.y >=  height - 15 && running) {
				var x_pos = island.x + levels[level].island_offset;
				if (trooper.x > x_pos - 15 && trooper.x < x_pos + levels[level].island_width + 20) {
					hits += 1;
					troopers.splice(trooper, 1);
				}
			}
		});

		updateStats();

		if (hits >= levels[level].goal && running) {
			troopers_left = levels[level].troopers_left;
			running = false;

			if (level == 10) {
				winGame();
			} else {
				updateInfo();
			}

			$('#info').show();
		}
		if (troopers_left == 0 && troopers.length == 0 && running) {
			running = false;
			level = 0;
			$('#stats_container').hide();
			$('#game_over').show();
		}
	}

	function updateInfo() {
		$('#info h1').text('Excellent Work!');
		$($('#info h2')[0]).text('Next Level: ' + (level + 1));
		$($('#info h2')[1]).text('');
	}

	function winGame() {
		$('#info h1').text('You Won!');
		$($('#info h2')[0]).text('Mission Accomplished!');
		$($('#info h2')[1]).text('A satisfactory number of the paratroopers made it to vacation alive.');
		$('button').remove();
		$('<a>', {
			href: 'paratroopers.html',
			text: 'Play Again?'
		}).appendTo('#info .inner_modal');
	}

	function updateStats() {
		$('.troopers').text('Troopers: ' + troopers_left);
		$('.hits').text('Hits: ' + hits);
		$('.goal').text('Goal: ' + levels[level].goal);
	}

	$(document).on('keypress', function (e) {
		console.log(e)
		if (e.charCode == 32 && troopers_left != 0 && running) {
			troopers_left--;
			troopers.push(new Trooper(plane.horizontal + 115, plane.vertical + 60, plane.v0x, 0));
		}
	});

	$('#start').on('click', function () {
		$('#stats_container').show();
		level++;
		troopers_left = levels[level].troopers_left;
		hits = 0;

		$('#info').hide();

		running = true;
	});

	setInterval(function () { arms_up = !arms_up; }, 70)

	$('body').disableSelection();

});

<commit_msg>bug fix<commit_after>(function($){
    $.fn.disableSelection = function() {
        return this
                 .attr('unselectable', 'on')
                 .css('user-select', 'none')
                 .on('selectstart', false);
    };
})(jQuery);

$(document).ready(function () {
	var canvas = $('canvas')[0],
		ctx = canvas.getContext('2d'),
		height = window.innerHeight - 40,
		width = window.innerWidth,
		plane = new Image(),
		tree = new Image(),
		time_interval = 30,
		troopers = [],
		arms_up = true,
		acceleration = 0.0001,
		level = 0,
		running = true,
		troopers_left = 5,
		hits = 0,

		island = {
			radius: 40,
			x: width / 2 - 60,
			y: height + 24
		},

		levels = [
		{
			island_width: 100,
			island_offset: 0,
			goal: 2,
			troopers_left: 5
		},
		{
			island_width: 100,
			island_offset: 0,
			goal: 2,
			troopers_left: 5
		},
		{
			island_width: 80,
			island_offset: 120,
			goal: 3,
			troopers_left: 5
		},
		{
			island_width: 80,
			island_offset: 200,
			goal: 5,
			troopers_left: 8
		},
		{
			island_width: 20,
			island_offset: 0,
			goal: 4,
			troopers_left: 8
		},
		{
			island_width: 100,
			island_offset: 200,
			goal: 3,
			troopers_left: 3
		},
		{
			island_width: 70,
			island_offset: 0,
			goal: 6,
			troopers_left: 8
		},
		{
			island_width: 50,
			island_offset: 150,
			goal: 6,
			troopers_left: 8
		},
		{
			island_width: 30,
			island_offset: 50,
			goal: 3,
			troopers_left: 5
		},
		{
			island_width: 20,
			island_offset: 250,
			goal: 4,
			troopers_left: 5
		},
		{
			island_width: 10,
			island_offset: 0,
			goal: 5,
			troopers_left: 5
		}
		];

	canvas.height = height;
	canvas.width = width;

	plane.horizontal = -200;
	plane.vertical = 50;
	plane.v0x = 0.1;

	plane.onload = function () {
		paintScreen();
	};

	plane.src = 'images/plane.png';
	tree.src = 'images/tree.png';

	function paintScreen() {
		checkTroopers();

		ctx.clearRect(0, 0, width, height);
		drawPlane();
		drawTroopers();
		drawIsland();
		evolvePlane();
		evolveTroopers();

		setTimeout(paintScreen, time_interval);
	};

	function drawPlane() {
		ctx.drawImage(plane, plane.horizontal, plane.vertical);
	};

	function evolvePlane() {
		plane.horizontal += plane.v0x*time_interval;

		if (plane.horizontal > width) {
			plane.horizontal = -200;
		}
	};

	function drawIsland() {
		var x_pos = island.x + levels[level].island_offset,
			island_width = levels[level].island_width;
		ctx.fillStyle = '#e88d15';
		ctx.beginPath();
		ctx.arc(x_pos, island.y, island.radius, 1.2 * Math.PI, 1.5 * Math.PI);
		ctx.lineTo(x_pos + island_width, island.y - island.radius);
		ctx.arc(x_pos + island_width, island.y, island.radius, 1.5 * Math.PI, 1.8 * Math.PI);
		ctx.closePath();
		ctx.fill();

		ctx.drawImage(tree, x_pos + island_width - 35, island.y - 155);
	}

	function Trooper(x, y, v0x, v0y) {
		this.x = x;
		this.y = y;
		this.x0 = x;
		this.y0 = y;
		this.v0x = v0x;
		this.v0y = v0y;
		this.time = 0;
	};

	function drawTroopers() {
		_.each(troopers, function (trooper) {
			ctx.fillStyle = '#11240e';
			ctx.beginPath();
			ctx.arc(trooper.x, trooper.y, 4, 0.5 * Math.PI, 2.5 * Math.PI);
			ctx.fill();
			ctx.lineWidth = 1.5;
			ctx.lineTo(trooper.x, trooper.y + 13);
			ctx.lineTo(trooper.x - 4, trooper.y + 25);
			ctx.moveTo(trooper.x, trooper.y + 13);
			ctx.lineTo(trooper.x + 4, trooper.y + 25);
			if (arms_up) {
				ctx.moveTo(trooper.x, trooper.y + 8);
				ctx.lineTo(trooper.x + 8, trooper.y + 7);
				ctx.moveTo(trooper.x, trooper.y + 8);
				ctx.lineTo(trooper.x - 8, trooper.y + 7);
			} else {
				ctx.moveTo(trooper.x, trooper.y + 8);
				ctx.lineTo(trooper.x + 7, trooper.y + 14);
				ctx.moveTo(trooper.x, trooper.y + 8);
				ctx.lineTo(trooper.x - 7, trooper.y + 14);
			}
			ctx.strokeStyle = '#11240e';
			ctx.stroke();
			ctx.closePath();
		});
	};

	function evolveTroopers() {
		_.each(troopers, function (trooper) {
			trooper.x = trooper.x0 + trooper.v0x * trooper.time;
			trooper.y = trooper.y0 + 0.5 * acceleration * Math.pow(trooper.time, 2);
			trooper.time += time_interval;
		});
	};

	function checkTroopers() {
		_.each(troopers, function (trooper) {
			if (trooper.y > height + 20) {
				troopers.splice(trooper, 1);
			}
			if (trooper.y >=  height - 15 && running) {
				var x_pos = island.x + levels[level].island_offset;
				if (trooper.x > x_pos - 20 && trooper.x < x_pos + levels[level].island_width + 20) {
					hits += 1;
					troopers.splice(trooper, 1);
				}
			}
		});

		updateStats();

		if (hits >= levels[level].goal && running) {
			troopers_left = levels[level].troopers_left;
			running = false;

			if (level == 10) {
				winGame();
			} else {
				updateInfo();
			}

			$('#info').show();
		}
		if (troopers_left == 0 && troopers.length == 0 && running) {
			running = false;
			level = 0;
			$('#stats_container').hide();
			$('#game_over').show();
		}
	}

	function updateInfo() {
		$('#info h1').text('Excellent Work!');
		$($('#info h2')[0]).text('Next Level: ' + (level + 1));
		$($('#info h2')[1]).text('');
	}

	function winGame() {
		$('#info h1').text('You Won!');
		$($('#info h2')[0]).text('Mission Accomplished!');
		$($('#info h2')[1]).text('A satisfactory number of the paratroopers made it to vacation alive.');
		$('button').remove();
		$('<a>', {
			href: 'paratroopers.html',
			text: 'Play Again?'
		}).appendTo('#info .inner_modal');
	}

	function updateStats() {
		$('.troopers').text('Troopers: ' + troopers_left);
		$('.hits').text('Hits: ' + hits);
		$('.goal').text('Goal: ' + levels[level].goal);
	}

	$(document).on('keypress', function (e) {
		console.log(e)
		if (e.charCode == 32 && troopers_left != 0 && running) {
			troopers_left--;
			troopers.push(new Trooper(plane.horizontal + 115, plane.vertical + 60, plane.v0x, 0));
		}
	});

	$('#start').on('click', function () {
		$('#stats_container').show();
		level++;
		troopers_left = levels[level].troopers_left;
		hits = 0;

		$('#info').hide();

		running = true;
	});

	setInterval(function () { arms_up = !arms_up; }, 70)

	$('body').disableSelection();

});

<|endoftext|>


<commit_before>#! /usr/bin/env node

/* A script for converting javascript challenge code into JSON.
  * Each challenge should have sections marked with comments '/// keyword:',
  * For example:
  *   /// solution:
  *   function MySolution()...
  *
  *   /// tests:
  *   assert(MySolution(2) === 3)...
  *
  * */

const commandLineArgs = require('command-line-args');
const fs = require('fs');
const acorn = require('acorn');

const optionDefinitions = [
  { name: 'force', type: Boolean, descr: 'Overwrite output files forcefully.' },
  { name: 'help', alias: 'h', type: Boolean, descr: 'Print help message' },
  { name: 'infile', alias: 'f', type: String, multiple: true, descr: 'Input files' },
  { name: 'outfile', alias: 'o', type: String, descr: 'Output JSON file' },
  { name: 'verbose', alias: 'v', type: Boolean, descr: 'Run in verbose mode' }
];

// Regexp definitions for the script
const re = {
  lineComment: /^\/\/\//,
  lineCommentWithProp: /^\/\/\/\s+(\w+):\s*$/,
  lineCommentWithPropAndText: /^\/\/\/\s+(\w+):\s*(\S.*)$/,
  lineCommentWithText: /^\/\/\/\s(.*)$/,
  endComment: /^\/\/\/\s+end\s+$/
};

const opts = commandLineArgs(optionDefinitions);

if (opts.help) {
  usage(0);
}

const expectedProps = {
  title: String,
  type: String,
  description: String,
  challengeSeed: 'Code',
  solutions: 'Code',
  tests: 'Code'
};

if (!opts.infile || opts.infile.length === 0) {
  console.error('Error. No input files were given.');
  usage(1);
}

const propParser = {
  state: 'IDLE',
  currFile: null,
  prop: null,
  propValue: [],
  files: {},
  continuedComments: false
};

opts.infile.forEach(file => {
  processFile(propParser, file, expectedProps);
});

const result = formatResult(propParser.files);

printToOutput(result);

//---------------------------------------------------------------------------
// HELPER FUNCTIONS
//---------------------------------------------------------------------------

function processFile(parser, file, props) {
  const buffer = fs.readFileSync(file);
  parser.currFile = file;
  parser.files[file] = {};
  checkFileSyntax(buffer);

  const lines = buffer.toString().split('\n');
  lines.forEach(line => {
    processLine(parser, line);
  });

  if (parser.propValue.length > 0) {
    finishCurrProp(parser);
  }

  verifyExpectedProps(parser, file, props);
}

/* Checks the code syntax in given buffer using acorn. */
function checkFileSyntax(buffer) {
  try {
    acorn.parse(buffer);
  }
  catch (err) {
    console.error(`Parsing failed: ${err}`);
    process.exit(1);
  }
}

/* Processes one line with regex and extracts prop values. */
function processLine(parser, line) {
  if (parser.continuedComments && !re.lineComment.test(line)) {
    finishCurrProp(parser);
    return;
  }

  if (re.lineCommentWithProp.test(line)) {
    const matches = line.match(re.lineCommentWithProp);
    if (parser.prop !== null) {
      finishCurrProp(parser);
    }
    parser.prop = matches[1];
  }
  else if (re.lineCommentWithPropAndText.test(line)) {
    const matches = line.match(re.lineCommentWithPropAndText);
    parser.prop = matches[1];
    parser.propValue.push(matches[2]);
    finishCurrProp(parser);
  }
  else if (re.lineCommentWithText.test(line)) {
    const matches = line.match(re.lineCommentWithPropAndText);
    parser.propValue.push(matches[1]);
    parser.continuedComments = true;
  }
  else if (re.endComment.test(line)) {
    finishCurrProp(parser);
  }
  else if (parser.prop !== null) {
    parser.propValue.push(line);
  }
}

/* Adds current property value into the parser for the current file being processed. Resets
 * the prop value after this. */
function finishCurrProp(parser) {
  const newPropVal = parser.propValue.length === 1 ? parser.propValue[0] : parser.propValue;

  if (typeof parser.files[parser.currFile][parser.prop] === 'undefined') {
    parser.files[parser.currFile][parser.prop] = newPropVal;
    parser.files[parser.currFile][parser.prop].num = 1;
  }
  else if (typeof parser.files[parser.currFile][parser.prop] === 'string') {
    const oldValue = parser.files[parser.currFile][parser.prop];
    parser.files[parser.currFile][parser.prop] = [oldValue, newPropVal];
    parser.files[parser.currFile][parser.prop].num = 2;
  }
  else if (typeof parser.files[parser.currFile][parser.prop] === 'object') {
    if (parser.files[parser.currFile][parser.prop].num === 1) {
      // Need to wrap the value in an array first.
      parser.files[parser.currFile][parser.prop] = [
        parser.files[parser.currFile][parser.prop],
        newPropVal
      ];
      parser.files[parser.currFile][parser.prop].num = 2;
    }
    else {
      parser.files[parser.currFile][parser.prop].push(newPropVal);
      parser.files[parser.currFile][parser.prop].num += 1;
    }
  }

  parser.propValue = [];
  parser.prop = null;
}

/* Verifies that the parsed file contains expected props like 'solution' etc.*/
function verifyExpectedProps(parser, file, props) {
  Object.keys(props).forEach(prop => {
    if (parser.files[file][prop] === undefined) {
      console.warn(`Prop ${prop} missing from file ${file}`);
    }
  });
}

/* Formats the result as JSON. */
function formatResult(parsedFiles) {
  const challenges = Object.keys(parsedFiles).map(filename =>
    parsedFiles[filename]
  );

  return JSON.stringify(challenges, null, 2);
}

/* Prints the results to given output file. */
function printToOutput (res) {
  if (opts.outfile) {
    if (!fs.existsSync(opts.outfile) || opts.force) {
      fs.writeFileSync(opts.outfile, res);
    }
  }
  else {
    console.log(res);
  }
}

/* Prints the usage of the script and exits. */
function usage(exitCode = 0) {
  console.log('Usage: bin/js2json_challenges.js [opts] <files>+\n');
  optionDefinitions.forEach(opt => {
    if (opt.alias) {
      console.log(`\t--${opt.name},-${opt.alias}\t- ${opt.descr}`);
    }
    else {
      console.log(`\t--${opt.name}\t\t- ${opt.descr}`);
    }
  });
  process.exit(exitCode);
}
<commit_msg>Produces now a json which is similar to fCC current seeds. Added name, time, order to the JSON output.<commit_after>#! /usr/bin/env node

/* A script for converting javascript challenge code into JSON.
  * Each challenge should have sections marked with comments '/// keyword:',
  * For example:
  *   /// solution:
  *   function MySolution()...
  *
  *   /// tests:
  *   assert(MySolution(2) === 3)...
  *
  * */

const commandLineArgs = require('command-line-args');
const fs = require('fs');
const acorn = require('acorn');

const optionDefinitions = [
  { name: 'force', type: Boolean, descr: 'Overwrite output files forcefully.' },
  { name: 'help', alias: 'h', type: Boolean, descr: 'Print help message' },
  { name: 'infile', alias: 'f', type: String, multiple: true, descr: 'Input files' },
  { name: 'outfile', alias: 'o', type: String, descr: 'Output JSON file' },
  { name: 'verbose', alias: 'v', type: Boolean, descr: 'Run in verbose mode' }
];

// Regexp definitions for the script
const re = {
  lineComment: /^\/\/\//,
  lineCommentWithProp: /^\/\/\/\s+(\w+):\s*$/,
  lineCommentWithPropAndText: /^\/\/\/\s+(\w+):\s*(\S.*)$/,
  lineCommentWithText: /^\/\/\/\s(.*)$/,
  endComment: /^\/\/\/\s+end\s+$/
};

const opts = commandLineArgs(optionDefinitions);

if (opts.help) {
  usage(0);
}

const expectedProps = {
  title: String,
  type: String,
  description: String,
  challengeSeed: 'Code',
  solutions: 'Code',
  tests: 'Code'
};

if (!opts.infile || opts.infile.length === 0) {
  console.error('Error. No input files were given.');
  usage(1);
}

const propParser = {
  state: 'IDLE',
  currFile: null,
  prop: null,
  propValue: [],
  files: {},
  continuedComments: false
};

opts.infile.forEach(file => {
  processFile(propParser, file, expectedProps);
});

const result = formatResult(propParser.files);

printToOutput(result);

//---------------------------------------------------------------------------
// HELPER FUNCTIONS
//---------------------------------------------------------------------------

function processFile(parser, file, props) {
  const buffer = fs.readFileSync(file);
  parser.currFile = file;
  parser.files[file] = {};
  checkFileSyntax(buffer);

  const lines = buffer.toString().split('\n');
  lines.forEach(line => {
    processLine(parser, line);
  });

  if (parser.propValue.length > 0) {
    finishCurrProp(parser);
  }

  verifyExpectedProps(parser, file, props);
}

/* Checks the code syntax in given buffer using acorn. */
function checkFileSyntax(buffer) {
  try {
    acorn.parse(buffer);
  }
  catch (err) {
    console.error(`Parsing failed: ${err}`);
    process.exit(1);
  }
}

/* Processes one line with regex and extracts prop values. */
function processLine(parser, line) {
  if (parser.continuedComments && !re.lineComment.test(line)) {
    finishCurrProp(parser);
    return;
  }

  if (re.lineCommentWithProp.test(line)) {
    const matches = line.match(re.lineCommentWithProp);
    if (parser.prop !== null) {
      finishCurrProp(parser);
    }
    parser.prop = matches[1];
  }
  else if (re.lineCommentWithPropAndText.test(line)) {
    const matches = line.match(re.lineCommentWithPropAndText);
    parser.prop = matches[1];
    parser.propValue.push(matches[2]);
    finishCurrProp(parser);
  }
  else if (re.lineCommentWithText.test(line)) {
    const matches = line.match(re.lineCommentWithPropAndText);
    parser.propValue.push(matches[1]);
    parser.continuedComments = true;
  }
  else if (re.endComment.test(line)) {
    finishCurrProp(parser);
  }
  else if (parser.prop !== null) {
    parser.propValue.push(line);
  }
}

/* Adds current property value into the parser for the current file being processed. Resets
 * the prop value after this. */
function finishCurrProp(parser) {
  const newPropVal = parser.propValue.length === 1 ? parser.propValue[0] : parser.propValue;

  if (typeof parser.files[parser.currFile][parser.prop] === 'undefined') {
    parser.files[parser.currFile][parser.prop] = newPropVal;
    parser.files[parser.currFile][parser.prop].num = 1;
  }
  else if (typeof parser.files[parser.currFile][parser.prop] === 'string') {
    const oldValue = parser.files[parser.currFile][parser.prop];
    parser.files[parser.currFile][parser.prop] = [oldValue, newPropVal];
    parser.files[parser.currFile][parser.prop].num = 2;
  }
  else if (typeof parser.files[parser.currFile][parser.prop] === 'object') {
    if (parser.files[parser.currFile][parser.prop].num === 1) {
      // Need to wrap the value in an array first.
      parser.files[parser.currFile][parser.prop] = [
        parser.files[parser.currFile][parser.prop],
        newPropVal
      ];
      parser.files[parser.currFile][parser.prop].num = 2;
    }
    else {
      parser.files[parser.currFile][parser.prop].push(newPropVal);
      parser.files[parser.currFile][parser.prop].num += 1;
    }
  }

  parser.propValue = [];
  parser.prop = null;
}

/* Verifies that the parsed file contains expected props like 'solution' etc.*/
function verifyExpectedProps(parser, file, props) {
  Object.keys(props).forEach(prop => {
    if (parser.files[file][prop] === undefined) {
      console.warn(`Prop ${prop} missing from file ${file}`);
    }
  });
}

/* Formats the result as JSON. */
function formatResult(parsedFiles) {
  const challenges = Object.keys(parsedFiles).map(filename =>
    parsedFiles[filename]
  );

  challenges.forEach(challenge => {
    challenge.id = parseInt(Math.random(), 16);
  });

  const finalFormat = {
    name: 'ArcadeMode Interview Questions',
    order: '',
    time: '',
    helpRoom: '',
    challenges
  };

  return JSON.stringify(finalFormat, null, 2);
}

/* Prints the results to given output file. */
function printToOutput (res) {
  if (opts.outfile) {
    if (!fs.existsSync(opts.outfile) || opts.force) {
      fs.writeFileSync(opts.outfile, res);
    }
  }
  else {
    console.log(res);
  }
}

/* Prints the usage of the script and exits. */
function usage(exitCode = 0) {
  console.log('Usage: bin/js2json_challenges.js [opts] <files>+\n');
  optionDefinitions.forEach(opt => {
    if (opt.alias) {
      console.log(`\t--${opt.name},-${opt.alias}\t- ${opt.descr}`);
    }
    else {
      console.log(`\t--${opt.name}\t\t- ${opt.descr}`);
    }
  });
  process.exit(exitCode);
}
<|endoftext|>


<commit_before>'use strict'

var mondo = require('../../lib/mondo')
var _ = require('lodash')

var nock = require('nock')

var mondoHelper = require('../helper/mondo-unit-spec-helper')
var mH = mondoHelper
var mondargs = mH.mondargs
var methodPaths = mondargs.api.resources

var knocker = mH.knocker
var testSuccess = mH.success
var testResponseError = mH.responseError
var testRequestError = mH.requestError

describe('Mondo unit tests', function () {
  beforeEach(function () {
    nock.cleanAll()
  })

  if (typeof Promise === 'undefined') {
    describe('Get a token', function () {
      function tokenNock () {
        var successCreds = _.extend({grant_type: 'password'}, mondargs.credentials)
        knocker({
          url: methodPaths.token,
          form: successCreds,
          auth: false
        })
        var invalidRequestCreds = _.extend({}, successCreds, { username: 'invalid' })
        knocker({
          url: methodPaths.token,
          form: invalidRequestCreds,
          auth: false,
          code: 400
        })
        var invalidClientCreds = _.extend({}, successCreds, {client_id: 'invalid'})
        knocker({
          url: methodPaths.token,
          form: invalidClientCreds,
          auth: false,
          code: 401
        })
      }
      beforeEach(function () {
        tokenNock()
      })

      it('should send correct token request when promises are not available', function (done) {
        mondo.token(mondargs.credentials, testSuccess(done))
      })
      it('should send handle token response failure when promises are not available', function (done) {
        mondo.token(_.extend({}, mondargs.credentials, { client_id: 'invalid' }), testResponseError(done))
      })
      it('should throw an error when promises are not available if no callback is passed', function (done) {
        try {
          mondo.token(mondargs.credentials)
        } catch (err) {
          expect(err.message).toEqual('method.missing.callback')
          done()
        }
      })
    })
  }
})
<commit_msg>Removed unnecessary promise variable<commit_after>'use strict'

var mondo = require('../../lib/mondo')
var _ = require('lodash')

var nock = require('nock')

var mondoHelper = require('../helper/mondo-unit-spec-helper')
var mH = mondoHelper
var mondargs = mH.mondargs
var methodPaths = mondargs.api.resources

var knocker = mH.knocker
var testSuccess = mH.success
var testResponseError = mH.responseError

describe('Mondo unit tests', function () {
  beforeEach(function () {
    nock.cleanAll()
  })

  if (typeof Promise === 'undefined') {
    describe('Get a token', function () {
      function tokenNock () {
        var successCreds = _.extend({grant_type: 'password'}, mondargs.credentials)
        knocker({
          url: methodPaths.token,
          form: successCreds,
          auth: false
        })
        var invalidRequestCreds = _.extend({}, successCreds, { username: 'invalid' })
        knocker({
          url: methodPaths.token,
          form: invalidRequestCreds,
          auth: false,
          code: 400
        })
        var invalidClientCreds = _.extend({}, successCreds, {client_id: 'invalid'})
        knocker({
          url: methodPaths.token,
          form: invalidClientCreds,
          auth: false,
          code: 401
        })
      }
      beforeEach(function () {
        tokenNock()
      })

      it('should send correct token request when promises are not available', function (done) {
        mondo.token(mondargs.credentials, testSuccess(done))
      })
      it('should send handle token response failure when promises are not available', function (done) {
        mondo.token(_.extend({}, mondargs.credentials, { client_id: 'invalid' }), testResponseError(done))
      })
      it('should throw an error when promises are not available if no callback is passed', function (done) {
        try {
          mondo.token(mondargs.credentials)
        } catch (err) {
          expect(err.message).toEqual('method.missing.callback')
          done()
        }
      })
    })
  }
})
<|endoftext|>


<commit_before>var projectModule = angular.module('Project', []);

projectModule.controller('projController',['$scope', function($scope){
  $scope.projects = [
    {
      name:'Web Application',
      description:"Built this website in MVC structure. Dealt with ",
      iconImage:'fa fa-desktop fa-stack-1x fa-inverse',
      urls: [
        {name: 'Fitbit Project',address: 'http://ec2-52-72-72-204.compute-1.amazonaws.com:8080/'},
        {name: 'Java Project',address: 'https://ide.c9.io/ricace/cloud_9_project_1'},
        {name: 'This Website',address: '#'}
      ]
    },
    {
      name:'Game Design',
      description:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima maxime quam architecto quo inventore harum ex magni, dicta impedit.',
      iconImage:'fa fa-laptop fa-stack-1x fa-inverse',
      urls: [
        {name: 'Fitbit Project',address: 'http://ec2-52-72-72-204.compute-1.amazonaws.com:8080/'},
        {name: 'Fitbit Project',address: 'http://ec2-52-72-72-204.compute-1.amazonaws.com:8080/'}
      ]
    },
    {
      name:'Sentiment Analysis',
      description:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima maxime quam architecto quo inventore harum ex magni, dicta impedit.',
      iconImage:'fa fa-file-word-o fa-stack-1x fa-inverse',
      urls: [
        {name: 'SentimentAnalysis',address: '/sentiment'},
        {name: 'Fitbit Project',address: 'http://ec2-52-72-72-204.compute-1.amazonaws.com:8080/'}
      ]
    }
  ];
}]);
<commit_msg>add jupyter notebook<commit_after>var projectModule = angular.module('Project', []);

projectModule.controller('projController',['$scope', function($scope){
  $scope.projects = [
    {
      name:'Web Application',
      description:"Built this website in MVC structure. Dealt with ",
      iconImage:'fa fa-desktop fa-stack-1x fa-inverse',
      urls: [
        {name: 'Fitbit Project',address: 'http://ec2-52-72-72-204.compute-1.amazonaws.com:8080/'},
        {name: 'Java Project',address: 'https://ide.c9.io/ricace/cloud_9_project_1'},
        {name: 'This Website',address: '#'}
      ]
    },
    {
      name:'Game Design',
      description:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima maxime quam architecto quo inventore harum ex magni, dicta impedit.',
      iconImage:'fa fa-laptop fa-stack-1x fa-inverse',
      urls: [
        {name: 'Fitbit Project',address: 'http://ec2-52-72-72-204.compute-1.amazonaws.com:8080/'},
        {name: 'Fitbit Project',address: 'http://ec2-52-72-72-204.compute-1.amazonaws.com:8080/'}
      ]
    },
    {
      name:'Sentiment Analysis',
      description:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima maxime quam architecto quo inventore harum ex magni, dicta impedit.',
      iconImage:'fa fa-file-word-o fa-stack-1x fa-inverse',
      urls: [
        {name: 'SentimentAnalysis',address: 'http://ec2-54-173-241-209.compute-1.amazonaws.com:8080/sentiment'},
        {name: 'Fitbit Project',address: 'http://ec2-52-72-72-204.compute-1.amazonaws.com:8080/'}
      ]
    }
  ];
}]);
<|endoftext|>


<commit_before>"use strict";

const ThemeBase = require('../themeBase');
const ServeDirectoryHandler = require('../router/handler/serveDirectoryHandler');
const path = require('path');

class ThemeBootstrap extends ThemeBase {
  constructor(engine) {
    super(engine);

    engine.plugin.get('Router')
      // Serve default CSS & JavaScript files.
      .addHandler(new ServeDirectoryHandler({
        id: 'ThemeBootstrap.DirectoryHandler',
        path: 'file/theme/themeBootstrap',
        target: path.join(__dirname, 'file'),
        menu: undefined,
        fileOptions: {},
        directoryOptions: undefined,
      }))
      // Serve Bootstrap files.
      .addHandler(new ServeDirectoryHandler({
        id: 'ThemeBootstrap.BootstrapDirectoryHandler',
        path: 'file/theme/bootstrap',
        target: path.join(path.dirname(require.resolve('bootstrap')), '..'),
        menu: undefined,
        fileOptions: {},
        directoryOptions: undefined,
      }));

    // Add the default Renderables.
    for (let renderable of [
      require('./renderable/page'),
    ]) {
      this.setRenderable(renderable);
    }
  }

  init() {
    // Declare the Bootstrap JS & CSS.
    this.engine.library.register({
      id: 'Bootstrap',
      css: [{
        id: 'Bootstrap',
        url: '/file/theme/bootstrap/css/bootstrap.css',
        path: path.join(path.dirname(require.resolve('bootstrap')), '../css/bootstrap.css'),
      }, {
        id: 'ThemeBootstrap',
        url: '/file/theme/themeBootstrap/css/themeBootstrap.css',
        path: path.join(__dirname, 'file/css/themeBootstrap.css'),
      }],
      jsFooter: [{
        id: 'Bootstrap',
        url: '/file/theme/bootstrap/js/bootstrap.min.js',
        path: path.join(path.dirname(require.resolve('bootstrap')), '../js/bootstrap.js'),
      }, {
        id: 'ThemeBootstrap',
        url: '/file/theme/themeBootstrap/js/themeBootstrap.js',
        path: path.join(__dirname, 'file/js/themeBootstrap.js'),
      }],
    });
    return super.init();
  }
}

module.exports = ThemeBootstrap;
<commit_msg>Add jQuery as dependency for Bootstrap<commit_after>"use strict";

const ThemeBase = require('../themeBase');
const ServeDirectoryHandler = require('../router/handler/serveDirectoryHandler');
const path = require('path');

class ThemeBootstrap extends ThemeBase {
  constructor(engine) {
    super(engine);

    engine.plugin.get('Router')
      // Serve default CSS & JavaScript files.
      .addHandler(new ServeDirectoryHandler({
        id: 'ThemeBootstrap.DirectoryHandler',
        path: 'file/theme/themeBootstrap',
        target: path.join(__dirname, 'file'),
        menu: undefined,
        fileOptions: {},
        directoryOptions: undefined,
      }))
      // Serve Bootstrap files.
      .addHandler(new ServeDirectoryHandler({
        id: 'ThemeBootstrap.BootstrapDirectoryHandler',
        path: 'file/theme/bootstrap',
        target: path.join(path.dirname(require.resolve('bootstrap')), '..'),
        menu: undefined,
        fileOptions: {},
        directoryOptions: undefined,
      }));

    // Add the default Renderables.
    for (let renderable of [
      require('./renderable/page'),
    ]) {
      this.setRenderable(renderable);
    }
  }

  init() {
    // Declare the Bootstrap JS & CSS.
    this.engine.library.register({
      id: 'Bootstrap',
      require: ['jQueryUI'],
      css: [{
        id: 'Bootstrap',
        url: '/file/theme/bootstrap/css/bootstrap.css',
        path: path.join(path.dirname(require.resolve('bootstrap')), '../css/bootstrap.css'),
      }, {
        id: 'ThemeBootstrap',
        url: '/file/theme/themeBootstrap/css/themeBootstrap.css',
        path: path.join(__dirname, 'file/css/themeBootstrap.css'),
      }],
      jsFooter: [{
        id: 'Bootstrap',
        url: '/file/theme/bootstrap/js/bootstrap.min.js',
        path: path.join(path.dirname(require.resolve('bootstrap')), '../js/bootstrap.js'),
      }, {
        id: 'ThemeBootstrap',
        url: '/file/theme/themeBootstrap/js/themeBootstrap.js',
        path: path.join(__dirname, 'file/js/themeBootstrap.js'),
      }],
    });
    return super.init();
  }
}

module.exports = ThemeBootstrap;
<|endoftext|>