차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판이전 판
다음 판
이전 판
tech:isotope [2016/09/19 14:16] V_Ltech:isotope [2021/05/28 07:54] (현재) V_L
줄 1: 줄 1:
 {{tag>isotope}} {{tag>isotope}}
 ====== Isotope ====== ====== Isotope ======
-{{INLINETOC}}+ 
  
 씨발 존 씨발 존
줄 9: 줄 9:
  
 존네좋군 존네좋군
 +
 +
  
 [[http://in-web.co.kr/developer-section/filter-%EC%99%80-sort-%EA%B8%B0%EB%8A%A5%EC%9D%84-%EA%B0%96%EC%B6%98-%EB%B0%98%EC%9D%91%ED%98%95-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83-js-%ED%94%8C%EB%9F%AC%EA%B7%B8%EC%9D%B8-isotope-js/|Filter 와 Sort 기능을 갖춘 반응형 레이아웃 js 플러그인 – isotope.js]] [[http://in-web.co.kr/developer-section/filter-%EC%99%80-sort-%EA%B8%B0%EB%8A%A5%EC%9D%84-%EA%B0%96%EC%B6%98-%EB%B0%98%EC%9D%91%ED%98%95-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83-js-%ED%94%8C%EB%9F%AC%EA%B7%B8%EC%9D%B8-isotope-js/|Filter 와 Sort 기능을 갖춘 반응형 레이아웃 js 플러그인 – isotope.js]]
 +
 +
 +http://jsfiddle.net/tahirahmed/ku2kyfow/
 +
 +
 +http://imagesloaded.desandro.com/
 +
 +http://purecss.io/layouts/side-menu/#
 +
 +
 +https://codepen.io/hanlinC/pen/dJwil
 +
 +
 +<file>
 +"use strict";
 +var resolve = {
 +    delay: function($q, $timeout) {
 +        var delay = $q.defer();
 +        return $timeout(delay.resolve, 0, !1), delay.promise
 +    }
 +};
 +angular.module("dropApp", ["ngCookies", "ngResource", "ngRoute", "ngSanitize", "ngProgress", "timer", "infinite-scroll"]).config(["$compileProvider", function($compileProvider) {
 +    $compileProvider.debugInfoEnabled(!1)
 +}]).config(["$routeProvider", "$locationProvider", "$httpProvider", function($routeProvider, $locationProvider, $httpProvider) {
 +    $routeProvider.when("/", {
 +        templateUrl: "views/main.html",
 +        controller: "MainCtrl",
 +        resolve: resolve
 +    }).when("/all", {
 +        templateUrl: "views/all.html",
 +        controller: "AllCtrl",
 +        resolve: resolve
 +    }).when("/create", {
 +        templateUrl: "views/create.html",
 +        controller: "CreateCtrl",
 +        resolve: resolve
 +    }).when("/featured", {
 +        templateUrl: "views/drop.html",
 +        controller: "DropCtrl",
 +        reloadOnSearch: !1,
 +        resolve: resolve
 +    }).when("/drop/:id", {
 +        templateUrl: "views/drop.html",
 +        controller: "DropCtrl",
 +        reloadOnSearch: !1,
 +        resolve: resolve
 +    }).otherwise({
 +        redirectTo: "/"
 +    }), $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
 +    var param = function(obj) {
 +        var name, value, fullSubName, subName, subValue, innerObj, i, query = "";
 +        for (name in obj)
 +            if (value = obj[name], value instanceof Array)
 +                for (i = 0; i < value.length; ++i) subValue = value[i], fullSubName = name + "[" + i + "]", innerObj = {}, innerObj[fullSubName] = subValue, query += param(innerObj) + "&";
 +            else if (value instanceof Object)
 +            for (subName in value) subValue = value[subName], fullSubName = name + "[" + subName + "]", innerObj = {}, innerObj[fullSubName] = subValue, query += param(innerObj) + "&";
 +        else void 0 !== value && null !== value && (query += encodeURIComponent(name) + "=" + encodeURIComponent(value) + "&");
 +        return query.length ? query.substr(0, query.length - 1) : query
 +    };
 +    $httpProvider.defaults.transformRequest = [function(data) {
 +        return angular.isObject(data) && "[object File]" !== String(data) ? param(data) : data
 +    }]
 +}]).run(["$rootScope", "$location", "$route", "$timeout", "Spotify", "ngProgress", function($rootScope, $location, $route, $timeout, Spotify, ngProgress) {
 +    var token_key = "access_token=",
 +        token_index = window.location.href.indexOf(token_key);
 +    if (token_index > -1) {
 +        var token = window.location.href.substr(token_index + token_key.length).split("&")[0];
 +        Spotify.set_access_token(token), $location.path("/create")
 +    }
 +    var oldLocation = "";
 +    $rootScope.$on("$routeChangeStart", function(angularEvent, next) {
 +        $rootScope.view_class = "view-" + $location.path().substr(1), ngProgress.reset();
 +        var isForwards = !0;
 +        if (next && next.$$route) {
 +            var newLocation = next.$$route.originalPath;
 +            oldLocation !== newLocation && -1 !== oldLocation.indexOf(newLocation) && (isForwards = !1), oldLocation = newLocation
 +        }
 +    }), ngProgress.color("#16e58a")
 +}]), angular.module("dropApp").service("Image", function() {
 +    function hexToRgb(hex) {
 +        var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
 +        return result ? {
 +            r: parseInt(result[1], 16),
 +            g: parseInt(result[2], 16),
 +            b: parseInt(result[3], 16)
 +        } : null
 +    }
 +    this.grayscale = function(pixels) {
 +        for (var d = pixels.data, i = 0; i < d.length; i += 4) {
 +            var r = d[i],
 +                g = d[i + 1],
 +                b = d[i + 2],
 +                v = .2126 * r + .7152 * g + .0722 * b;
 +            d[i] = d[i + 1] = d[i + 2] = v
 +        }
 +        return pixels
 +    }, this.duotone = function(img, tone1, tone2) {
 +        var gradient = this.gradientMap(tone1, tone2);
 +        img = this.grayscale(img);
 +        for (var d = img.data, i = 0; i < d.length; i += 4) d[i] = gradient[4 * d[i]], d[i + 1] = gradient[4 * d[i + 1] + 1], d[i + 2] = gradient[4 * d[i + 2] + 2];
 +        return img
 +    }, this.gradientMap = function(tone1, tone2) {
 +        for (var rgb1 = hexToRgb(tone1), rgb2 = hexToRgb(tone2), gradient = [], i = 0; 1024 > i; i += 4) gradient[i] = ((256 - i / 4) * rgb1.r + i / 4 * rgb2.r) / 256, gradient[i + 1] = ((256 - i / 4) * rgb1.g + i / 4 * rgb2.g) / 256, gradient[i + 2] = ((256 - i / 4) * rgb1.b + i / 4 * rgb2.b) / 256, gradient[i + 3] = 255;
 +        return gradient
 +    }, this.flipImage = function(input) {
 +        for (var tempCtx = document.createElement("canvas").getContext("2d"), output = tempCtx.createImageData(input.width, input.height), w = input.width, h = input.height, inputData = input.data, outputData = output.data, y = 1; h - 1 > y; y += 1)
 +            for (var x = 1; w - 1 > x; x += 1)
 +                for (var i = 4 * (y * w + x), flip = 4 * (y * w + (w - x)), c = 0; 4 > c; c += 1) outputData[i + c] = inputData[flip + c];
 +        return output
 +    }
 +}), angular.module("dropApp").service("BlockFormatter", function() {
 +    this.format_media = function(media, parent) {
 +        var block = {};
 +        switch (block.type = "media", block.media_type = media.drop_type, block.title = media.title ? media.title : "Check out this exclusive " + media.drop_type + "!", block.description = media.description ? media.description : "Love " + parent.name + "? Don't miss this!", block.url = "/drop/" + media.artist_id + "?media=" + media.id, media.drop_type) {
 +            case "video":
 +                block.call_to_action = "watch now";
 +                break;
 +            case "gallery":
 +                block.call_to_action = "gallery";
 +                break;
 +            case "playlist":
 +                block.call_to_action = "follow"
 +        }
 +        return block
 +    }, this.format_drop = function(data) {
 +        var block = {};
 +        return block.type = "drop", block.title = data.name, block.image = data.files[data.featured_image_id].url, block.url = "/drop/" + data.id, block.call_to_action = "view drop", block
 +    }
 +}), angular.module("dropApp").service("Spotify", ["$http", "$location", "$window", "$q", function($http, $location, $window, $q) {
 +    var access_token, user, client_id = "d8c2bf8b2663462e93004f0575f821e8",
 +        redirect_uri = "http://spotify-thedrop.com/",
 +        authorization_url = "https://accounts.spotify.com/authorize",
 +        api_base = "https://api.spotify.com/v1";
 +    this.set_access_token = function(token) {
 +        access_token = token
 +    }, this.get_access_token = function() {
 +        return access_token
 +    }, this.authenticate = function() {
 +        var url_string = authorization_url + "?response_type=token&client_id=" + client_id + "&redirect_uri=" + redirect_uri;
 +        $window.location.href = url_string
 +    }, this.get_user = function() {
 +        var deferred = $q.defer();
 +        return user ? deferred.resolve(user) : $http({
 +            url: api_base + "/me",
 +            headers: {
 +                Authorization: "Bearer " + access_token
 +            }
 +        }).success(function(response) {
 +            deferred.resolve(user = response)
 +        }).error(function(response) {
 +            deferred.reject()
 +        }), deferred.promise
 +    }
 +}]), angular.module("dropApp").service("Api", ["$http", "$q", function($http, $q) {
 +    function card_shim(raw) {
 +        for (var i = 0; i < raw.length; i++) raw[i].type = "card";
 +        return raw
 +    }
 +
 +    function drop_shim(data) {
 +        function get_image_url(id) {
 +            return data.files[id] ? data.files[id].url : null
 +        }
 +
 +        function get_image_content_url(i, id) {
 +            return data.content[i].files[id] ? data.content[i].files[id].url : null
 +        }
 +        var now = (new Date).getTime();
 +        data.type = "drop", data.featured_image = get_image_url(data.featured_image_id), data.header_image = get_image_url(data.header_image_id), data.dropped_at = moment(data.reveal_date).fromNow(), data.single_uri = "spotify:track:" + data.single, data.dropped = moment(data.release_date).isBefore(now), "i" === data.dropped_at.charAt(0) && "n" === data.dropped_at.charAt(1) ? data.dropped_at = "Dropping " + data.dropped_at : data.dropped_at = "Dropped " + data.dropped_at, data.card_images = [];
 +        var card_image_1 = get_image_url(data.artist_image1_id),
 +            card_image_2 = get_image_url(data.artist_image2_id),
 +            card_image_3 = get_image_url(data.artist_image3_id);
 +        if (card_image_1 && data.card_images.push(card_image_1), card_image_2 && data.card_images.push(card_image_2), card_image_3 && data.card_images.push(card_image_3), data.content)
 +            for (var i = 0; i < data.content.length; i++) {
 +                var content = data.content[i];
 +                content.item_index = i, content.type = "media", content.media_type = content.content_type, content.media_index = i, content.featured_image = get_image_content_url(i, content.featured_image_id), content.dropped_at = moment(content.release_date).fromNow(), content.drop_id = data.id, content.locked = moment(content.release_date).isAfter(now)
 +            }
 +        return data
 +    }
 +    var drops, cards, ads, base = "http://api.spotify-thedrop.com";
 +    this.get_drop = function(id) {
 +        var deferred = $q.defer();
 +        return $http.get(base + "/drop/" + id + "/").success(function(response) {
 +            deferred.resolve(drop_shim(response))
 +        }), deferred.promise
 +    }, this.get_all_drops = function() {
 +        var deferred = $q.defer();
 +        return drops ? deferred.resolve(drops) : $http.get(base + "/drops").success(function(response) {
 +            for (var i = 0; i < response.length; i++) response[i] = drop_shim(response[i]);
 +            deferred.resolve(drops = response)
 +        }), deferred.promise
 +    }, this.get_featured = function() {
 +        var deferred = $q.defer();
 +        return $http.get(base + "/drops?featured=1").success(function(response) {
 +            deferred.resolve(drop_shim(response[response.length - 1]))
 +        }), deferred.promise
 +    }, this.get_cards = function() {
 +        var deferred = $q.defer();
 +        return cards ? deferred.resolve(cards) : $http.get(base + "/cards?featured=1/").success(function(response) {
 +            cards = card_shim(response), deferred.resolve(cards)
 +        }), deferred.promise
 +    }, this.get_single_card = function(route) {
 +        var deferred = $q.defer();
 +        return cards ? deferred.resolve(cards) : $http.get(route).success(function(response) {
 +            deferred.resolve(response)
 +        }), deferred.promise
 +    }, this.get_ad = function() {
 +        var deferred = $q.defer(),
 +            addArray = [];
 +        return ads ? deferred.resolve(ads) : $http.get(base + "/brands").success(function(response) {
 +            if ("object" == typeof response) {
 +                var adObj = {
 +                        type: "ad",
 +                        image: "images/mc-ad-blue.jpg",
 +                        description: "It takes two to tango with a 20 piece.",
 +                        content_url: ""
 +                    },
 +                    add_timestamp = function(url) {
 +                        return url ? String(url).replace("[timestamp]", (new Date).getTime()) : ""
 +                    },
 +                    setObj = function(responseObj) {
 +                        adObj.image = responseObj.files[responseObj.image_id].url, adObj.description = responseObj.title, adObj.content_url = responseObj.content_url, adObj.ad_url = add_timestamp(responseObj.ad_url), adObj.ad_text_url = add_timestamp(responseObj.ad_text_url), adObj.ad_text_url || (adObj.ad_text_url = adObj.ad_url), adObj.tracking_pixel_url = add_timestamp(responseObj.tracking_pixel_url), addArray.push(angular.copy(adObj))
 +                    };
 +                response = response.sort(function(a, b) {
 +                    return a.id == b.id ? 0 : a.id > b.id ? -1 : 1
 +                });
 +                for (var i = 0; i < response.length; i++) setObj(response[i])
 +            }
 +            deferred.resolve(addArray)
 +        }), deferred.promise
 +    }, this.save_card = function(card_data, image) {
 +        var deferred = $q.defer(),
 +            data = {
 +                drop_id: card_data.drop.id,
 +                creator_id: card_data.user.id,
 +                image: image
 +            };
 +        return $http({
 +            method: "POST",
 +            url: base + "/card/",
 +            data: data,
 +            headers: {
 +                "Content-Type": "application/x-www-form-urlencoded"
 +            }
 +        }).success(function(response, status, headers, config) {
 +            deferred.resolve("" + base + headers().location)
 +        }), deferred.promise
 +    }
 +}]), angular.module("dropApp").controller("MainCtrl", ["$scope", "$timeout", "$q", "$location", "Api", "ngProgress", function($scope, $timeout, $q, $location, Api, ngProgress) {
 +    $scope.items = [];
 +    var featured = 0;
 +    $scope.selectFeature = function(setFeature) {
 +        featured = setFeature
 +    }, $scope.isFeatured = function(checkFeature) {
 +        return featured === checkFeature
 +    }, this.load_featured_drop = function() {
 +        Api.get_featured().then(function(response) {
 +            ngProgress.complete(), $scope.featured = response, $scope.$on("imageLoaded", function() {
 +                $timeout(function() {
 +                    $scope.backgroundLoaded = !0, $scope.firstLoad = !0;
 +                    media: for (var i = $scope.featured.content.length; i--; i >= 0)
 +                        if (!$scope.featured.content[i].locked) {
 +                            $scope.items.unshift($scope.featured.content[i]), $scope.items[0].name = $scope.featured.name, $timeout(function() {
 +                                $scope.firstLoad = !1
 +                            }, 1e3);
 +                            break media
 +                        }
 +                    $timeout(function() {
 +                        Api.get_ad().then(function(response) {
 +                            $scope.items.push(response[0])
 +                        }), $scope.ready = !0
 +                    }, 1600)
 +                }, 700)
 +            })
 +        })
 +    };
 +    var random_drops, ad_blocks, counter = 0;
 +    $scope.load_random_assets = function() {
 +        ngProgress.start(), $q.all([Api.get_all_drops(), Api.get_ad()]).then(function(response) {
 +            ngProgress.complete(), random_drops = angular.copy(response[0]), ad_blocks = angular.copy(response[1]), $scope.add_random_assets()
 +        })
 +    }, $scope.add_random_assets = function() {
 +        if (counter++, $scope.ready = !1, !random_drops || !random_drops.length) return $scope.load_random_assets(), !1;
 +        for (var random_items = [], random_index = Math.floor(Math.random() * (random_drops.length - 9)), random_range = random_drops.splice(random_index, 10), i = 0; i < random_range.length; i++) {
 +            var selected_drop = random_range[i],
 +                selected_drop_media_length = selected_drop.content ? selected_drop.content.length : 0,
 +                selected_random_index = Math.floor(Math.random() * (selected_drop_media_length + 1));
 +            selected_random_index === selected_drop_media_length ? random_items.push(selected_drop) : (selected_drop.content[selected_random_index].name = selected_drop.name, random_items.push(selected_drop.content[selected_random_index]))
 +        }
 +        if (counter % 2 === 0) {
 +            var shuffle = function(a) {
 +                var j, x, i;
 +                for (i = a.length; i; i -= 1) j = Math.floor(Math.random() * i), x = a[i - 1], a[i - 1] = a[j], a[j] = x;
 +                return a
 +            };
 +            random_items = shuffle(random_items);
 +            var shuffle_merge = function(source, target) {
 +                for (var sourceInds = [], result = [], i = 0; i < source.length; i++) sourceInds.push(i);
 +                sourceInds = shuffle(shuffle(sourceInds)).slice(0, target.length).sort();
 +                for (var currentInd = sourceInds.shift(), i = 0; i < source.length; i++) i == currentInd && (result.push(target.pop()), currentInd = sourceInds.shift()), result.push(source[i]);
 +                return result
 +            };
 +            random_items = shuffle_merge(random_items, ad_blocks)
 +        }
 +        $scope.items = $scope.items.concat(random_items), $scope.ready = !0
 +    }, this.load_featured_drop()
 +}]), angular.module("dropApp").controller("HeaderCtrl", ["$scope", "$location", function($scope, $location) {
 +    $scope.links = [{
 +        title: "FEATURED",
 +        path: "/drop/featured",
 +        color: "#fae62d"
 +    }, {
 +        title: "ALL",
 +        path: "/all",
 +        color: "#9bf0e1"
 +    }], $scope.timestamp = (new Date).getTime(), $scope.visisble = !0, $scope.toggleShare = function(toggle) {
 +        var $shareButtons = $(".share-button"),
 +            buttonsNum = $shareButtons.length,
 +            buttonsMid = buttonsNum / 3,
 +            spacing = 90;
 +        $scope.visisble && "close" !== toggle ? ($shareButtons.each(function(i) {
 +            var $cur = $(this),
 +                pos = i - 1,
 +                dist = Math.abs(pos);
 +            $cur.css({
 +                zIndex: buttonsMid - dist
 +            }), TweenMax.to($cur, 1.1 * dist, {
 +                x: pos * spacing,
 +                y: 90,
 +                scale: .95,
 +                width: 60,
 +                height: 60,
 +                ease: Elastic.easeOut,
 +                easeParams: [1.01, .5]
 +            }), TweenMax.to($cur, .8, {
 +                delay: .2 * dist - .1,
 +                scale: .95,
 +                width: 60,
 +                height: 60,
 +                ease: Elastic.easeOut,
 +                easeParams: [1.1, .6]
 +            }), TweenMax.fromTo($cur.children(".share-icon"), .2, {
 +                scale: 0
 +            }, {
 +                delay: .2 * dist - .1,
 +                scale: 1,
 +                ease: Quad.easeInOut
 +            })
 +        }), $scope.visisble = !$scope.visisble) : "close" === toggle ? ($shareButtons.each(function(i) {
 +            var $cur = $(this),
 +                pos = i,
 +                dist = Math.abs(pos);
 +            $cur.css({
 +                zIndex: dist
 +            }), TweenMax.to($cur, .4 + .1 * (buttonsMid - dist), {
 +                x: 0,
 +                y: 0,
 +                scale: 0,
 +                width: 32,
 +                height: 32,
 +                ease: Quad.easeInOut
 +            }), TweenMax.to($cur.children(".share-icon"), .2, {
 +                scale: 0,
 +                ease: Quad.easeIn
 +            })
 +        }), $scope.visisble = !0) : ($shareButtons.each(function(i) {
 +            var $cur = $(this),
 +                pos = i,
 +                dist = Math.abs(pos);
 +            $cur.css({
 +                zIndex: dist
 +            }), TweenMax.to($cur, .4 + .1 * (buttonsMid - dist), {
 +                x: 0,
 +                y: 0,
 +                scale: 0,
 +                width: 32,
 +                height: 32,
 +                ease: Quad.easeInOut
 +            }), TweenMax.to($cur.children(".share-icon"), .2, {
 +                scale: 0,
 +                ease: Quad.easeIn
 +            })
 +        }), $scope.visisble = !0)
 +    }, $scope.$on("$locationChangeSuccess", function(e, next) {
 +        $scope.path = $location.path(), $scope.toggleShare("close")
 +    }), $scope.path = $location.path()
 +}]), angular.module("dropApp").controller("FeaturedCtrl", ["$scope", "$timeout", "$q", "$location", "Api", "ngProgress", function($scope, $timeout, $q, $location, Api, ngProgress) {
 +    $scope.items = [], this.load_featured_drop = function() {
 +        ngProgress.start(), Api.get_featured().then(function(response) {
 +            ngProgress.complete(), $timeout(function() {
 +                $scope.featured = response;
 +                media: for (var i = $scope.quantity; i--; i >= 0)
 +                    if (!$scope.featured.content[i].locked) {
 +                        $scope.items.unshift($scope.featured.content[i]);
 +                        break media
 +                    }
 +                Api.get_ad().then(function(response) {
 +                    $scope.items.push(response[0])
 +                }), $scope.ready = !0
 +            }, 500)
 +        })
 +    };
 +    var random_drops, random_cards;
 +    $scope.load_random_assets = function() {
 +        ngProgress.start(), $q.all([Api.get_all_drops(), Api.get_cards()]).then(function(response) {
 +            ngProgress.complete(), random_drops = angular.copy(response[0]), random_cards = angular.copy(response[1]), $scope.add_random_assets()
 +        })
 +    }, $scope.add_random_assets = function() {
 +        if ($scope.ready = !1, !random_drops || !random_drops.length) return $scope.load_random_assets(), !1;
 +        for (var random_items = [], random_index = Math.floor(Math.random() * (random_drops.length - 4)), random_range = random_drops.splice(random_index, 5), i = 0; i < random_range.length; i++) {
 +            var selected_drop = random_range[i],
 +                selected_drop_media_length = selected_drop.content ? selected_drop.content.length : 0,
 +                selected_random_index = Math.floor(Math.random() * (selected_drop_media_length + 1));
 +            selected_random_index === selected_drop_media_length ? random_items.push(selected_drop) : random_items.push(selected_drop.content[selected_random_index])
 +        }
 +        if (random_cards.length) {
 +            var random_card_index = Math.floor(Math.random() * (random_items.length - 1));
 +            random_items.splice(random_card_index, 0, random_cards.pop())
 +        }
 +        $scope.items = $scope.items.concat(random_items), $scope.ready = !0
 +    }, this.load_featured_drop()
 +}]), angular.module("dropApp").controller("AllCtrl", ["$scope", "$timeout", "Api", "ngProgress", function($scope, $timeout, Api, ngProgress) {
 +    $scope.limit = 6, $scope.limit_per_page = 6, $scope.visible = !1, this.load_drops = function() {
 +        ngProgress.start(), Api.get_all_drops().then(function(response) {
 +            ngProgress.complete(), $timeout(function() {
 +                $scope.drops = response.reverse(), $scope.visible = !0
 +            }, 500)
 +        })
 +    }, $scope.background = "/images/auth/all.jpg", $scope.next_page = function() {
 +        $scope.limit = $scope.limit + $scope.limit_per_page
 +    }, this.load_drops()
 +}]), angular.module("dropApp").controller("CreateCtrl", ["$scope", "$q", "$timeout", "Api", "Spotify", "ngProgress", function($scope, $q, $timeout, Api, Spotify, ngProgress) {
 +    $scope.card = {}, $scope.imageUrl = "spotify-thedrop.com", $scope.auth_blocked = !Spotify.get_access_token(), $scope.auth_blocked || (ngProgress.start(), $scope.auth_blocked = !1, $q.all([Spotify.get_user(), Api.get_all_drops()]).then(function(response) {
 +        ngProgress.complete(), $scope.card.drop = response[1][0], $scope.card.track = $scope.card.drop.song_list[0], $scope.$watch("card.drop", function() {
 +            $scope.card.track = $scope.card.drop.song_list[0], $scope.randomize()
 +        }, !0), $timeout(function() {
 +            $timeout(function() {
 +                $scope.drops = response[1], $scope.card.user = response[0]
 +            }, 500)
 +        }, 500)
 +    }, function(response) {
 +        ngProgress.complete(), $scope.auth_blocked = !0, console.log("error")
 +    })), $scope.authenticate = function() {
 +        Spotify.authenticate()
 +    }, $scope.themes = [{
 +        text: "#F59B23",
 +        foreground: "#AF2896",
 +        background: "#503750",
 +        value: 0
 +    }, {
 +        text: "#2D46B9",
 +        foreground: "#CDF564",
 +        background: "#FF4632",
 +        value: 1
 +    }, {
 +        text: "#F573A0",
 +        foreground: "#9BF0E1",
 +        background: "#503750",
 +        value: 2
 +    }, {
 +        text: "#000000",
 +        foreground: "#FAE62D",
 +        background: "#F037A5",
 +        value: 3
 +    }], $scope.background = "/images/auth/auth.png", $scope.bursts = ["/images/bursts/triangle.png", "/images/bursts/rectangle.png", "/images/bursts/circle.png"], $scope.select_type = function(type) {
 +        $scope.card.type = type
 +    }, $scope.select_burst = function(burst) {
 +        $scope.card.burst = burst
 +    }, $scope.select_image = function(image) {
 +        $scope.card.image = image
 +    }, $scope.select_theme = function(theme) {
 +        $scope.card.theme = theme
 +    }, $scope.scale_background = function() {
 +        $scope.card.scale = !$scope.card.scale
 +    }, $scope.flip_background = function() {
 +        $scope.card.flip = !$scope.card.flip
 +    }, $scope.rotate_background = function() {
 +        $scope.card.rotation = $scope.card.rotation < 3 ? ++$scope.card.rotation : 0
 +    }, $scope.drag_background = function() {
 +        $scope.drag = !$scope.drag
 +    }, $scope.randomize = function() {
 +        $scope.card.type = Math.random() >= .5 ? "burst" : "image", $scope.card.image = $scope.card.drop ? $scope.card.drop.card_images[Math.floor(Math.random() * $scope.card.drop.card_images.length)] : "", $scope.card.burst = $scope.bursts[Math.floor(Math.random() * $scope.bursts.length)], $scope.card.theme = $scope.themes[Math.floor(Math.random() * $scope.themes.length)], $scope.card.rotation = Math.floor(3 * Math.random()), $scope.card.flip = Math.random() >= .5, $scope.card.scale = Math.random() >= .5
 +    }
 +}]), angular.module("dropApp").controller("DropCtrl", ["$scope", "$routeParams", "$timeout", "$location", "Api", function($scope, $routeParams, $timeout, $location, Api) {
 +    function load_drop() {
 +        isNaN($routeParams.id) ? Api.get_featured().then(render_drop) : Api.get_drop($routeParams.id).then(render_drop)
 +    }
 +
 +    function render_drop(drop) {
 +        "i" === drop.dropped_at.charAt(0) || "i" === drop.dropped_at.charAt(5) ? drop.dropped = !1 : drop.dropped = !0, $scope.drop = drop, $scope.drop.album_uri = "spotify:album:" + $scope.drop.album_uri, $scope.drop.endpoint = "http://open.spotify.com/" + $scope.drop.album_uri.replace("spotify:", "").replace(/:/g, "/"), $scope.spotify = "/images/spotify.png";
 +        for (var i = $scope.drop.content.length; i--; i >= 0) $scope.drop.content[i].locked ? $scope.drop.content.splice($scope.drop.content.length, 0, $scope.drop.content.splice($scope.drop.content[i], 1)[0]) : $scope.items.unshift($scope.drop.content[i]);
 +        Api.get_ad().then(function(response) {
 +            $scope.items.push(response[0])
 +        }), $timeout(function() {
 +            $scope.$broadcast("timer-start")
 +        }, 400), $scope.$on("$routeUpdate", $scope.on_route_update), $scope.on_route_update()
 +    }
 +    $scope.items = [], $scope.clickWatch = 0, $scope.set_media = function(index) {
 +        $location.search("media", index), $scope.clickWatch++
 +    }, $scope.clear_media = function() {
 +        $(".youtube-player iframe").remove(), $location.url($location.path())
 +    }, $scope.on_route_update = function() {
 +        $scope.media_index = $location.search().media, $scope.media = $scope.drop.content[$scope.media_index]
 +    }, load_drop()
 +}]), angular.module("dropApp").directive("audioPlayer", function() {
 +    return {
 +        scope: {
 +            uri: "=audioPlayerUri",
 +            albumUri: "=audioPlayerAlbumUri",
 +            revealDate: "=audioPlayerRevealDate"
 +        },
 +        link: function(scope, element) {
 +            var base = '<iframe src="https://embed.spotify.com/?uri={uri}" width="100%" height="100%" frameborder="0" allowtransparency="true"></iframe>';
 +            scope.afterRelease = !1, scope.$watch("revealDate", function() {
 +                if (scope.revealDate) {
 +                    var revealDate = moment(scope.revealDate),
 +                        currentDate = moment(),
 +                        diff = currentDate.diff(revealDate, "seconds");
 +                    scope.afterRelease = diff > 0 ? !0 : !1
 +                }
 +            }), scope.$watch("albumUri", function() {
 +                scope.afterRelease && (scope.albumUri ? (element.html(base.replace("{uri}", scope.albumUri)), setTimeout(function() {
 +                    element.addClass("activated album")
 +                }, 500)) : element.removeClass("activated"))
 +            }), scope.$watch("uri", function() {
 +                scope.afterRelease || (scope.uri ? (element.html(base.replace("{uri}", scope.uri)), setTimeout(function() {
 +                    element.addClass("activated")
 +                }, 500)) : element.removeClass("activated"))
 +            })
 +        }
 +    }
 +}), angular.module("dropApp").directive("slider", function() {
 +    return {
 +        scope: {
 +            options: "=sliderOptions",
 +            switcher: "=clickWatch"
 +        },
 +        templateUrl: "/partials/slider.html",
 +        transclude: !0,
 +        controller: ["$scope", function($scope) {
 +            this.initialize = function() {
 +                $scope.init()
 +            }
 +        }],
 +        link: function(scope, element) {
 +            var defaults = {
 +                grabCursor: !0,
 +                pagination: $(element).find(".swiper-pagination"),
 +                nextButton: $(element).find(".swiper-button-next"),
 +                prevButton: $(element).find(".swiper-button-prev"),
 +                paginationClickable: !0,
 +                preloadImages: !1,
 +                lazyLoading: !0
 +            };
 +            scope.$watch("switcher", function() {
 +                $(".swiper-slide .swiper-lazy").each(function(idx) {
 +                    self = $(this), $(this).attr("src") && (self.removeClass("swiper-lazy-loaded"), self.removeAttr("src"), setTimeout(function() {
 +                        s.lazy.load()
 +                    }))
 +                })
 +            });
 +            var s, options = angular.extend(defaults, scope.options);
 +            scope.init = function() {
 +                s && s.destroy(), setTimeout(function() {
 +                    s = new Swiper(element[0], options)
 +                }, 100)
 +            }
 +        }
 +    }
 +}), angular.module("dropApp").directive("sliderItem", function() {
 +    return {
 +        require: "^slider",
 +        link: function(scope, element, attrs, sliderCtrl) {
 +            scope.$last && sliderCtrl.initialize()
 +        }
 +    }
 +}), angular.module("dropApp").directive("mediaCircle", function() {
 +    return {
 +        templateUrl: "partials/media-circle.html",
 +        link: function(scope, element) {
 +            var r = 4 * Math.random() + 2.5,
 +                t = .25 * Math.PI,
 +                labelX = r + r * Math.cos(t),
 +                labelY = r + r * Math.sin(t);
 +            scope.circleStyle = {
 +                width: 2 * r + "em",
 +                height: 2 * r + "em"
 +            }, scope.labelStyle = {
 +                top: labelY + "em",
 +                left: labelX + "em"
 +            }, setTimeout(function() {
 +                element.addClass("revealed")
 +            }, 200 * scope.$index + 1500)
 +        }
 +    }
 +}), angular.module("dropApp").directive("imageLoader", function() {
 +    return {
 +        scope: {
 +            imageLoaderSrc: "=imageLoaderSrc"
 +        },
 +        template: '<div class="image-loader-element" ng-style="backgroundImage"></div><div class="image-loader-progress"></div>',
 +        link: function(scope, element, attrs) {
 +            function loadImage() {
 +                image = new Image, image.onload = onImageLoaded, image.src = scope.imageLoaderSrc, element.removeClass("image-loader-complete").addClass("image-loader-loading")
 +            }
 +
 +            function onImageLoaded() {
 +                void 0 !== attrs.backgroundImage && scope.$emit("imageLoaded"), element.removeClass("image-loader-loading").addClass("image-loader-complete").children().first().css("background-image", "url(" + scope.imageLoaderSrc + ")")
 +            }
 +
 +            function onImageError() {
 +                element.removeClass("image-loader-loading").removeClass("image-loader-complete")
 +            }
 +            var image;
 +            scope.$watch("imageLoaderSrc", function(val) {
 +                val ? setTimeout(function() {
 +                    loadImage()
 +                }, 300) : onImageError()
 +            })
 +        }
 +    }
 +}), angular.module("dropApp").directive("gallery", function() {
 +    return {
 +        scope: {
 +            items: "=galleryItems"
 +        },
 +        templateUrl: "partials/gallery.html",
 +        link: function(scope, element, attrs) {
 +            scope.gallerySliderOptions = {
 +                slidesPerView: 1,
 +                pagination: ".swiper-pagination",
 +                nextButton: ".swiper-button-next",
 +                prevButton: ".swiper-button-prev",
 +                paginationClickable: !0,
 +                preloadImages: !1,
 +                lazyLoading: !0,
 +                loop: !0
 +            }
 +        }
 +    }
 +}), angular.module("dropApp").directive("youtubePlayer", ["$sce", "$timeout", function($sce, $timeout) {
 +    return {
 +        scope: {
 +            data: "=youtubePlayer"
 +        },
 +        templateUrl: "partials/videoplayer.html",
 +        link: function(scope, element, attrs) {
 +            var id, base = "http://www.youtube.com/embed/{id}?autoplay=1&showinfo=0&rel=0&autohide=1&showinfo=0&enablejsapi=1&playerapiid=ytplaye";
 +            scope.visible = !1, scope.$watch("data", function() {
 +                if (scope.data && scope.data.content) {
 +                    if (!scope.data.content.url) return void scope.stop();
 +                    id = scope.data.content.url.split("watch?v=")[1], $timeout(scope.play, 500)
 +                } else scope.stop()
 +            }), scope.play = function() {
 +                scope.iframe_url = $sce.trustAsResourceUrl(base.replace("{id}", id)), scope.playing = !0
 +            }, scope.stop = function() {
 +                scope.iframe_url = $sce.trustAsResourceUrl("about:blank"), scope.playing = !1
 +            }, window.uploadDone = function() {
 +                scope.data && (scope.visible = !0, scope.$apply())
 +            }
 +        }
 +    }
 +}]), angular.module("dropApp").directive("packery", function() {
 +    return {
 +        scope: !0,
 +        controller: ["$scope", function($scope) {
 +            this.initialize = function() {
 +                $scope.init()
 +            }
 +        }],
 +        link: function(scope, element, attrs) {
 +            var p, defaults = {
 +                itemSelector: ".block-item",
 +                percentPosition: !0,
 +                masonry: {
 +                    columnWidth: ".block-item-small"
 +                }
 +            };
 +            scope.init = function() {
 +                setTimeout(function() {
 +                    p = new Isotope(element[0], defaults)
 +                }, 200), setTimeout(function() {
 +                    p.arrange()
 +                }, 300)
 +            }
 +        }
 +    }
 +}), angular.module("dropApp").directive("packeryItem", function() {
 +    return {
 +        require: "^packery",
 +        link: function(scope, element, attrs, packeryCtrl) {
 +            scope.$last && packeryCtrl.initialize()
 +        }
 +    }
 +}), angular.module("dropApp").directive("blockItem", function() {
 +    return {
 +        scope: {
 +            data: "=blockItemData"
 +        },
 +        template: '<div ng-include="get_template_url()"></div>',
 +        link: function(scope, element, attrs) {
 +            function generate_media_cta(type) {
 +                switch (type) {
 +                    case "video":
 +                        return "watch now";
 +                    case "playlist":
 +                        return "listen";
 +                    case "single":
 +                        return "listen";
 +                    case "gallery":
 +                        return "view now";
 +                    case "ad":
 +                        return "watch now";
 +                    default:
 +                        return "view " + type
 +                }
 +            }
 +
 +            function get_image_url(id, files) {
 +                return files[id] ? files[id].url : null
 +            }
 +
 +            function build_card() {
 +                switch (scope.data.type) {
 +                    case "card":
 +                        scope.template_url = "partials/block-item-card.html", scope.cta = "create your card", scope.image = get_image_url(scope.data.image_id, scope.data.files), element.addClass("block-item-small block-item-card");
 +                        break;
 +                    case "ad":
 +                        scope.template_url = "partials/block-item-ad.html", scope.cta = "", scope.ad_url = scope.data.ad_url, scope.tracking_pixel_url = scope.data.tracking_pixel_url, element.addClass("block-item-small block-item-ad");
 +                        break;
 +                    case "media":
 +                        scope.template_url = "partials/block-item-media.html", scope.cta = generate_media_cta(scope.data.media_type), element.addClass("video" === scope.data.media_type ? "block-item-large" : "block-item-small");
 +                        break;
 +                    case "drop":
 +                        scope.template_url = "partials/block-item-drop.html", scope.cta = "view drop", element.addClass("block-item-small")
 +                }
 +                if (!scope.data.image && !scope.data.featured_image) {
 +                    var random_drop_style = Math.floor(5 * Math.random());
 +                    element.addClass("drop-style-" + random_drop_style)
 +                }
 +            }
 +            scope.$watch("data", function(val) {
 +                val && build_card()
 +            }), scope.get_template_url = function() {
 +                return scope.template_url
 +            }, scope.show_ad_video = function(youtube_id) {
 +                if (youtube_id) {
 +                    var iframeHtml = '<iframe width="560" height="315" style="z-index: 2" src="http://www.youtube.com/embed/' + youtube_id + '?autoplay=1&showinfo=0" frameborder="0" allowfullscreen></iframe>';
 +                    $.fancybox(iframeHtml, {
 +                        title: "",
 +                        closeBtn: !1,
 +                        closeClick: !0,
 +                        width: 560,
 +                        height: 300,
 +                        autoSize: !1,
 +                        autoHeight: !1,
 +                        scrolling: !1,
 +                        helpers: {
 +                            overlay: {
 +                                closeClick: !0,
 +                                locked: !1,
 +                                css: {
 +                                    position: "fixed",
 +                                    width: "100%",
 +                                    height: "100%",
 +                                    top: 0,
 +                                    left: 0,
 +                                    background: "rgba(50,50,50, 0.7)",
 +                                    zIndex: 0
 +                                }
 +                            }
 +                        }
 +                    })
 +                }
 +            }, scope.is_playing = !1, scope.toggle_music = function() {
 +                scope.is_playing ? (scope.is_playing = !1, element.removeClass("block-item-playing"), scope.audio_uri = null) : (scope.is_playing = !0, element.addClass("block-item-playing"), scope.audio_uri = "spotify:track:1XALSFY5nrFQ9NaI2XNp9t")
 +            }
 +        }
 +    }
 +}), angular.module("dropApp").directive("dropCard", ["Image", "Api", function(Image, Api) {
 +    return {
 +        scope: !1,
 +        restrict: "A",
 +        link: function(scope, element, attrs) {
 +            function render_background() {
 +                var is_burst = "burst" === scope.card.type;
 +                background.onImageLoaded(function() {
 +                    var img_data = background.getOriginalImageData();
 +                    img_data = Image.duotone(img_data, scope.card.theme.background, scope.card.theme.foreground), img_data = scope.card.flip ? Image.flipImage(img_data) : img_data, background.setImageData(img_data), background.setRotation(is_burst ? 90 * scope.card.rotation : 0), background.update(!is_burst && scope.card.scale ? {
 +                        w: 900,
 +                        h: 900,
 +                        x: -300,
 +                        y: -300
 +                    } : {
 +                        w: 450,
 +                        h: 450,
 +                        x: -75,
 +                        y: -75
 +                    })
 +                }), card.background.update({
 +                    fill: scope.card.theme.background
 +                }), background.changeURL(is_burst ? scope.card.burst : scope.card.image)
 +            }
 +
 +            function render_text() {
 +                return scope.card.track ? (text.song.changeText(scope.card.track), text.songxs.changeText(""), text.artist.changeText(scope.card.drop.album), text.song.w > 270 ? (text.song.changeText(""), text.songxs.changeText(scope.card.track), format_text("small"), text.songxs.w > 270 && text.songxs.truncate(270)) : format_text("normal"), void(text.artist.w > 200 && text.artist.truncate(200))) : !1
 +            }
 +
 +            function format_text(type) {
 +                switch (type) {
 +                    case "small":
 +                        text.headline.update({
 +                            y: 100
 +                        }), text.songxs.update({
 +                            y: 138
 +                        }), text.from.update({
 +                            y: 170
 +                        }), text.artist.update({
 +                            y: 170
 +                        });
 +                        break;
 +                    default:
 +                        text.headline.update({
 +                            y: 100
 +                        }), text.song.update({
 +                            y: 145
 +                        }), text.from.update({
 +                            y: 178
 +                        }), text.artist.update({
 +                            y: 178
 +                        })
 +                }
 +                for (var t in text) text[t].update({
 +                    fill: scope.card.theme.text
 +                })
 +            }
 +
 +            function render_user() {
 +                if (scope.card.user) {
 +                    var img = new window.Image;
 +                    img.crossOrigin = "Anonymous", img.onload = function() {
 +                        var c = document.createElement("canvas"),
 +                            ctx = c.getContext("2d");
 +                        ctx.beginPath(), ctx.arc(25, 25, 25, 0, 2 * Math.PI, !0), ctx.closePath(), ctx.fill(), ctx.clip(), ctx.drawImage(this, 0, 0, 50, 50);
 +                        var d = ctx.getImageData(0, 0, 50, 50);
 +                        avatar.setImageData(d), avatar.update({
 +                            y: 15
 +                        })
 +                    }, img.src = scope.card.user.images[0].url, username.changeText(scope.card.user.display_name), username.update({
 +                        y: 35
 +                    })
 +                }
 +            }
 +
 +            function onMouseLeave() {
 +                is_dragging = !1
 +            }
 +
 +            function onMouseDown(x, y) {
 +                drag_position.x = x - background.x, drag_position.y = y - background.y, is_dragging = !0
 +            }
 +
 +            function onMouseUp() {
 +                is_dragging = !1
 +            }
 +
 +            function onMouseMove(x, y) {
 +                if (is_dragging) {
 +                    var _x = x - drag_position.x,
 +                        _y = y - drag_position.y;
 +                    _x >= -1 ? _x = -1 : _x + background.w <= card.width - 1 && (_x = card.width - background.w + 1), _y >= -1 ? _y = -1 : _y + background.h <= card.height - 1 && (_y = card.height - background.h + 1), background.update({
 +                        x: _x,
 +                        y: _y
 +                    })
 +                }
 +            }
 +            var card = new Postcard(element[0], {
 +                    filename: "dropcard.png"
 +                }),
 +                background = card.addImage("background", ""),
 +                avatar = (card.addImage("bottomLogos", "/images/bottomlogos.png", {
 +                    x: 0,
 +                    y: 260,
 +                    w: 300,
 +                    h: 40
 +                }), card.addImage("avatar", "/images/sample-profile.png", {
 +                    x: 15,
 +                    y: -45,
 +                    w: 35,
 +                    h: 35
 +                })),
 +                username = card.addText("username", "", 10, {
 +                    x: 58,
 +                    y: -35,
 +                    family: "light",
 +                    size: "14px"
 +                }),
 +                text = {
 +                    headline: card.addText("intro", "I'm feeling", 10, {
 +                        x: 15,
 +                        y: -15,
 +                        family: "light",
 +                        size: "20px"
 +                    }),
 +                    song: card.addText("song", "", 10, {
 +                        x: 15,
 +                        y: 128,
 +                        family: "bold",
 +                        size: "40px"
 +                    }),
 +                    songxs: card.addText("song.small", "", 10, {
 +                        x: 15,
 +                        y: 121,
 +                        family: "bold",
 +                        size: "30px"
 +                    }),
 +                    from: card.addText("from", "from", 10, {
 +                        x: 15,
 +                        y: -15,
 +                        family: "light",
 +                        size: "20px"
 +                    }),
 +                    artist: card.addText("artist", "", 10, {
 +                        x: 63,
 +                        y: -15,
 +                        family: "bold",
 +                        size: "20px"
 +                    }),
 +                    cta: card.addText("cta", "Album out now", 10, {
 +                        x: 15,
 +                        y: -15,
 +                        family: "light",
 +                        size: "15px"
 +                    })
 +                };
 +            scope.refresh = function() {
 +                scope.saved = !1, render_background(), render_text(), render_user()
 +            }, scope.$watch("card", scope.refresh, !0), scope.randomize();
 +            var is_dragging = !1,
 +                drag_position = {};
 +            scope.$watch("drag", function() {
 +                scope.drag ? (element.css("cursor", "move").bind("mouseleave", onMouseLeave), card.onMouseDown(onMouseDown), card.onMouseUp(onMouseUp), card.onMouseMove(onMouseMove)) : (element.css("cursor", "auto"), card.clearMouseEvents())
 +            }), scope.save = function() {
 +                Api.save_card(scope.card, card["export"]()).then(function(response) {
 +                    scope.saved = !0, Api.get_single_card(response).then(function(data) {
 +                        scope.imageUrl = encodeURIComponent(data.files[data.image_id].url)
 +                    })
 +                })
 +            }, scope.download = function(event) {
 +                card.save(event)
 +            }, PostcardTextObject.prototype.truncate = function(width) {
 +                for (var t = this.text, i = 0; this.w > width;) this.changeText(t.substr(0, t.length - ++i) + "...")
 +            }
 +        }
 +    }
 +}]), angular.module("dropApp").directive("mediaIcon", function() {
 +    return {
 +        scope: {
 +            media: "=mediaIcon"
 +        },
 +        link: function(scope, element, attrs) {
 +            scope.$watch("media", function() {
 +                if (element.removeClass(), scope.media.locked) element.replaceWith('<div class="exlusive-video"><img src="/images/icons/Locked-white.svg"><span>Locked Content</span></div>');
 +                else switch (scope.media.media_type) {
 +                    case "video":
 +                        element.replaceWith('<div class="exlusive-video"><img src="/images/icons/Video-white.svg"><span>Exclusive Video</span></div>');
 +                        break;
 +                    case "playlist":
 +                        element.replaceWith('<div class="exlusive-video"><img src="/images/icons/Playlist-white.svg"><span>Exclusive Playlist</span></div>');
 +                        break;
 +                    case "single":
 +                        element.addClass("fa fa-play");
 +                        break;
 +                    case "gallery":
 +                        element.replaceWith('<div class="exlusive-video"><img src="/images/icons/Gallery-white.svg"><span>Exclusive Gallery</span></div>')
 +                }
 +            })
 +        }
 +    }
 +});
 +</file>