<commit_before>angular.module('SmoothScrollbar', [])
    .service('ScrollbarService', class ScrollbarService{
        static $inject = ['$q'];

        constructor($q) {
            this.scrollbarInstances = {};
            this.deferreds = {};
            this.$q = $q;
        }

        /**
         * @method
         * Get scrollbar instance
         * If instance isn't existed,
         * callback wiil be invoked after instance is created
         *
         * @param {String} name: scrollbar name
         */
        getInstance(name) {
            const { scrollbarInstances, deferreds, $q } = this;

            if (scrollbarInstances.hasOwnProperty(name)) {
                return ($q.resolve || $q.when)(scrollbarInstances[name]);
            }

            let deferred = deferreds[name] = deferreds[name] || $q.defer();

            return deferred.promise;
        }

        /**
         * @method
         * Create scrollbar instance
         *
         * @param {String} name: scrollbar name
         * @param {Element} elem: container element
         * @param {Object} options: as is explained in scrollbar constructor
         *
         * @return {Scrollbar} scrollbar instance
         */
        createInstance(name, elem, options) {
            const { scrollbarInstances, deferreds } = this;

            if (scrollbarInstances.hasOwnProperty(name)) {
                return scrollbarInstances[name];
            }

            let instance = scrollbarInstances[name] = new Scrollbar(elem, options);

            if (deferreds.hasOwnProperty(name)) {
                deferreds[name].resolve(instance);
            }

            return instance;
        }

        /**
         * @method
         * Destroy scrollbar instance
         *
         * @param {String} name: scrollbar name
         */
        destroyInstance(name) {
            let { scrollbarInstances, deferreds } = this;
            let instance = scrollbarInstances[name];

            if (instance) {
                instance.destroy();
                delete scrollbarInstances[name];
                delete deferreds[name];
            }
        }
    })
    .directive('scrollbar', ['ScrollbarService', (ScrollbarService) => {
        return {
            restrict: 'AE',
            transclude: true,
            template: `
                <article class="scroll-content" ng-transclude></article>
                <aside class="scrollbar-track scrollbar-track-x">
                    <div class="scrollbar-thumb scrollbar-thumb-x"></div>
                </aside>
                <aside class="scrollbar-track scrollbar-track-y">
                    <div class="scrollbar-thumb scrollbar-thumb-y"></div>
                </aside>
            `,
            scope: {
                speed: '@',
                stepLength: '@',
                easingDuration: '@',
                easingCurve: '@',
                propagation: '='
            },
            link(scope, elem, attrs) {
                const name = attrs.scrollbar || attrs.name || Date.now().toString(32);

                const scrollbar = ScrollbarService.createInstance(name, elem[0], scope);

                let original = {
                    update: ::scrollbar.update,
                    scrollTo: ::scrollbar.scrollTo,
                    addListener: ::scrollbar.addListener,
                    infiniteScroll: ::scrollbar.infiniteScroll
                };

                let applyChange = (cb) => {
                    if (typeof cb !== 'function') return;

                    return (...args) => {
                        cb(...args);
                        scope.$apply();
                    };
                };

                scrollbar.update = (cb) => {
                    original.update(applyChange(cb));
                };

                scrollbar.scrollTo = (x, y, duration, cb) => {
                    original.scrollTo(x, y, duration, applyChange(cb));
                };

                scrollbar.addListener = (cb) => {
                    if (typeof cb !== 'function') return;

                    original.addListener(applyChange(cb));
                };

                scrollbar.infiniteScroll = (cb, threshold) => {
                    if (typeof cb !== 'function') return;

                    original.infiniteScroll(applyChange(cb), threshold);
                };

                scope.$on('$destroy', () => {
                    ScrollbarService.destroyInstance(name);
                });
            }
        };<commit_msg>refact: use Scrollbar.init() to build instance<commit_after>angular.module('SmoothScrollbar', [])
    .constant('SCROLLBAR_VERSION', Scrollbar.version)
    .service('ScrollbarService', class ScrollbarService{
        static $inject = ['$q'];

        constructor($q) {
            this.scrollbarInstances = {};
            this.deferreds = {};
            this.$q = $q;
        }

        /**
         * @method
         * Get scrollbar instance
         * If instance isn't existed,
         * callback wiil be invoked after instance is created
         *
         * @param {String} name: scrollbar name
         */
        getInstance(name) {
            const { scrollbarInstances, deferreds, $q } = this;

            if (scrollbarInstances.hasOwnProperty(name)) {
                return ($q.resolve || $q.when)(scrollbarInstances[name]);
            }

            let deferred = deferreds[name] = deferreds[name] || $q.defer();

            return deferred.promise;
        }

        /**
         * @method
         * Create scrollbar instance
         *
         * @param {String} name: scrollbar name
         * @param {Element} elem: container element
         * @param {Object} options: as is explained in scrollbar constructor
         *
         * @return {Scrollbar} scrollbar instance
         */
        createInstance(name, elem, options) {
            const { scrollbarInstances, deferreds } = this;

            if (scrollbarInstances.hasOwnProperty(name)) {
                return scrollbarInstances[name];
            }

            let instance = scrollbarInstances[name] = Scrollbar.init(elem, options);

            if (deferreds.hasOwnProperty(name)) {
                deferreds[name].resolve(instance);
            }

            return instance;
        }

        /**
         * @method
         * Destroy scrollbar instance
         *
         * @param {String} name: scrollbar name
         */
        destroyInstance(name) {
            let { scrollbarInstances, deferreds } = this;
            let instance = scrollbarInstances[name];

            if (instance) {
                instance.destroy();
                delete scrollbarInstances[name];
                delete deferreds[name];
            }
        }
    })
    .directive('scrollbar', ['ScrollbarService', (ScrollbarService) => {
        return {
            restrict: 'AE',
            transclude: true,
            scope: {
                speed: '@',
                stepLength: '@',
                easingDuration: '@',
                easingCurve: '@',
                propagation: '='
            },
            link(scope, elem, attrs, ctrl, transclude) {
                const { speed, stepLength, easingDuration, easingCurve } = scope;
                const name = attrs.scrollbar || attrs.name || Date.now().toString(32);

                const scrollbar = ScrollbarService.createInstance(name, elem[0], scope);

                let original = {
                    update: ::scrollbar.update,
                    scrollTo: ::scrollbar.scrollTo,
                    addListener: ::scrollbar.addListener,
                    infiniteScroll: ::scrollbar.infiniteScroll
                };

                let applyChange = (cb) => {
                    if (typeof cb !== 'function') return;

                    return (...args) => {
                        cb(...args);
                        scope.$apply();
                    };
                };

                scrollbar.update = (cb) => {
                    original.update(applyChange(cb));
                };

                scrollbar.scrollTo = (x, y, duration, cb) => {
                    original.scrollTo(x, y, duration, applyChange(cb));
                };

                scrollbar.addListener = (cb) => {
                    if (typeof cb !== 'function') return;

                    original.addListener(applyChange(cb));
                };

                scrollbar.infiniteScroll = (cb, threshold) => {
                    if (typeof cb !== 'function') return;

                    original.infiniteScroll(applyChange(cb), threshold);
                };

                scope.$on('$destroy', () => {
                    ScrollbarService.destroyInstance(name);
                });

                const $scrollContent = angular.element(scrollbar.targets.content);

                transclude((clones) => {
                    $scrollContent.append(clones);
                });
            }
        };
{'fraction_non_alphanumeric': 0.11473229132025274, 'fraction_numerical': 0.0006651147322913202, 'mean_word_length': 1.3556135770234987, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1228738', 'n_tokens_mistral': 2313, 'n_tokens_neox': 2142, 'n_words': 447}