text:
describe('NgTableParams', function () {
    var scope, ctrl, data = [
        {name: "Moroni", age: 50, role: 'Administrator'},
        {name: "Tiancum", age: 43, role: 'Administrator'},
        {name: "Jacob", age: 27, role: 'Administrator'},
        {name: "Nephi", age: 29, role: 'Moderator'},
        {name: "Enos", age: 34, role: 'User'},
        {name: "Tiancum", age: 43, role: 'User'},
        {name: "Jacob", age: 27, role: 'User'},
        {name: "Nephi", age: 29, role: 'Moderator'},
        {name: "Enos", age: 34, role: 'User'},
        {name: "Tiancum", age: 43, role: 'Moderator'},
        {name: "Jacob", age: 27, role: 'User'},
        {name: "Nephi", age: 29, role: 'User'},
        {name: "Enos", age: 34, role: 'Moderator'},
        {name: "Tiancum", age: 43, role: 'User'},
        {name: "Jacob", age: 27, role: 'User'},
        {name: "Nephi", age: 29, role: 'User'},
        {name: "Enos", age: 34, role: 'User'}
    ];
    var NgTableParams,
        $rootScope;

    beforeEach(function () {
        // Initialize the service provider
        // by injecting it to a fake module's config block
        var fakeModule = angular.module('test.config', function () {});
        fakeModule.config( function ($provide) {
            $provide.decorator('ngTableDefaultGetData', createSpy);

            createSpy.$inject = ['$delegate'];
            function createSpy(ngTableDefaultGetData){
                return jasmine.createSpy('ngTableDefaultGetDataSpy',ngTableDefaultGetData).and.callThrough();
            }
        });
        // Initialize test.app injector
        module('ngTable', 'test.config');

    });

    beforeEach(inject(function ($controller, _$rootScope_, _NgTableParams_) {
        $rootScope = _$rootScope_;
        scope = $rootScope.$new();
        NgTableParams = _NgTableParams_;
    }));

    function createNgTableParams(settings) {
        var initialParams;
        if (arguments.length === 2){
            initialParams = arguments[0];
            settings = arguments[1];
        }

        settings = angular.extend({}, {
            filterDelay: 0
        }, settings);
        var tableParams = new NgTableParams(initialParams, settings);
        spyOn(tableParams.settings(), 'getData').and.callThrough();
        return tableParams;
    }

    it('NgTableParams should be defined', function () {
        expect(NgTableParams).toBeDefined();
    });

    describe('generatePagesArray', function(){
        it('should generate pages array using arguments supplied', function(){
            var params = new NgTableParams();
            expect(params.generatePagesArray(1, 30, 10)).toEqual([
                { type: 'prev', number: 1, active: false },
                { type: 'first', number: 1, active: false, current: true },
                { type: 'page', number: 2, active: true, current: false },
                { type: 'last', number: 3, active: true, current: false },
                { type: 'next', number: 2, active: true }
            ]);
            expect(params.generatePagesArray(2, 30, 10)).toEqual([
                { type: 'prev', number: 1, active: true },
                { type: 'first', number: 1, active: true, current: false },
                { type: 'page', number: 2, active: false, current: true },
                { type: 'last', number: 3, active: true, current: false },
                { type: 'next', number: 3, active: true }
            ]);
            expect(params.generatePagesArray(2, 100, 10)).toEqual([
                { type: 'prev', number: 1, active: true },
                { type: 'first', number: 1, active: true, current: false },
                { type: 'page', number: 2, active: false, current: true },
                { type: 'page', number: 3, active: true, current: false },
                { type: 'page', number: 4, active: true, current: false },
                { type: 'page', number: 5, active: true, current: false },
                { type: 'page', number: 6, active: true, current: false },
                { type: 'page', number: 7, active: true, current: false },
                { type: 'more', active: false },
                { type: 'last', number: 10, active: true, current: false },
                { type: 'next', number: 3, active: true }
            ]);
        });

        it('should use own parameter values to generate pages when no arguments supplied', function(){
            var params = new NgTableParams({ page: 2, count: 10 }, { total: 30 });

            expect(params.generatePagesArray()).toEqual([
                { type: 'prev', number: 1, active: true },
                { type: 'first', number: 1, active: true, current: false },
                { type: 'page', number: 2, active: false, current: true },
                { type: 'last', number: 3, active: true, current: false },
                { type: 'next', number: 3, active: true }
            ]);

        });
    });

    it('NgTableParams `page` parameter', function () {
        var params = new NgTableParams();

        expect(params.page()).toBe(1);
        expect(params.page(2)).toEqual(params);
        expect(params.page()).toBe(2);

        params = new NgTableParams({
            page: 3
        });
        expect(params.page()).toBe(3);
    });

    it('NgTableParams parse url parameters', function () {
        var params = new NgTableParams({
            'sorting[name]': 'asc',
            'sorting[age]': 'desc',
            'filter[name]': 'test',
            'filter[age]': 20
        });

        expect(params.filter()).toEqual({ 'name': 'test', 'age': 20 });
        expect(params.filter({})).toEqual(params);

        expect(params.sorting()).toEqual({ 'age': 'desc' }); // sorting only by one column
        expect(params.sorting({})).toEqual(params);
    });

    it('NgTableParams return url parameters', function () {
        var params = new NgTableParams({
            'sorting[name]': 'asc',
            'sorting[age]': 'desc',
            'filter[name]': 'test',
            'filter[age]': 20
        });
        expect(params.url()).toEqual({
            'page': '1',
            'count': '1',
            'filter[name]': 'test',
            'filter[age]': 20,
            'sorting[age]': 'desc'
        });
        expect(params.url(true)).toEqual([
            'page=1',
            'count=1',
            'filter[name]=test',
            'filter[age]=20',
            'sorting[age]=desc'
        ]);
    });

    it('NgTableParams test orderBy', function () {
        var params = new NgTableParams({
            'sorting[name]': 'asc'
        });

        expect(params.orderBy()).toEqual([ '+name' ]); // for angular sorting function

        params.sorting({ name: 'desc', age: 'asc' });

        expect(params.orderBy()).toEqual([ '-name', '+age' ]);
    });

    it('NgTableParams test settings', function () {
        var params = new NgTableParams();

        expect(params.settings()).toEqual(jasmine.objectContaining({
            $loading: false,
            data: null,
            total: 0,
            defaultSort : 'desc',
            counts: [10, 25, 50, 100],
            interceptors: [],
            paginationMaxBlocks: 11,
            paginationMinBlocks: 5,
            sortingIndicator : 'span',
            getData: params.getData,
            getGroups: params.getGroups,
            filterDelay: 750
        }));

        params = new NgTableParams({}, { total: 100, counts: [1,2] });

        expect(params.settings()).toEqual(jasmine.objectContaining({
            $loading: false,
            data: null,
            total: 100,
            defaultSort : 'desc',
            counts: [1,2],
            interceptors: [],
            paginationMaxBlocks: 11,
            paginationMinBlocks: 5,
            sortingIndicator : 'span',
            getData: params.getData,
            getGroups: params.getGroups,
            filterDelay: 750
        }));
    });

    it('changing settings().data should reset page to 1', function(){
        // given
        var tableParams = createNgTableParams({ count: 1, page: 2 }, { data: [1,2,3]});
        tableParams.reload();
        scope.$digest();
        expect(tableParams.page()).toBe(2); // checking assumptions

        // when
        tableParams.settings({ data: [1,2,3, 4]});

        // then
        expect(tableParams.page()).toBe(1);
    });

    describe('reload', function(){

        it('should call getData to retrieve data', function(){
            var tp = createNgTableParams();
            tp.reload();
            scope.$digest();
            expect(tp.settings().getData.calls.count()).toBe(1);
        });

        it('should add the results returned by getData to the data field', function(){
            var tp = createNgTableParams({ getData: function(){
                return [1,2,3];
            }});
            tp.reload();
            scope.$digest();
            expect(tp.data).toEqual([1,2,3]);
        });

        it('should use ngTableDefaultGetData function when NgTableParams not supplied a getData function', inject(function(ngTableDefaultGetData){
            // given
            var tp = createNgTableParams();

            // when
            tp.reload();
            scope.$digest();

            // then
            expect(ngTableDefaultGetData).toHaveBeenCalled();
        }));

        it('should propagate rejection reason from getData', inject(function($q){
            // given
            var tp = createNgTableParams({ getData: function(){
                return $q.reject('bad response')
            }});

            // when
            var actualRejection;
            tp.reload().catch(function(reason){
                actualRejection = reason;
            });
            scope.$digest();

            // then
            expect(actualRejection).toBe('bad response');
        }));
    });

    it('NgTableParams test grouping', inject(function ($rootScope) {
        var tp = createNgTableParams({ getData: function (/*params*/) {
            return data;
        }});

        var actualRoleGroups;
        tp.getGroups('role'/*, params*/).then(function(groups){
            actualRoleGroups = groups;
        });
        $rootScope.$digest();

        expect(actualRoleGroups).toEqual([
            {
                value: 'Administrator',
                data: [
                    {name: "Moroni", age: 50, role: 'Administrator'},
                    {name: "Tiancum", age: 43, role: 'Administrator'},
                    {name: "Jacob", age: 27, role: 'Administrator'}
                ]
            },
            {
                value: 'Moderator',
                data: [
                    {name: "Nephi", age: 29, role: 'Moderator'},
                    {name: "Nephi", age: 29, role: 'Moderator'},
                    {name: "Tiancum", age: 43, role: 'Moderator'},
                    {name: "Enos", age: 34, role: 'Moderator'}
                ]
            },
            {
                value: 'User',
                data: [
                    {name: "Enos", age: 34, role: 'User'},
                    {name: "Tiancum", age: 43, role: 'User'},
                    {name: "Jacob", age: 27, role: 'User'},
                    {name: "Enos", age: 34, role: 'User'},
                    {name: "Jacob", age: 27, role: 'User'},
                    {name: "Nephi", age: 29, role: 'User'},
                    {name: "Tiancum", age: 43, role: 'User'},
                    {name: "Jacob", age: 27, role: 'User'},
                    {name: "Nephi", age: 29, role: 'User'},
                    {name: "Enos", age: 34, role: 'User'}
                ]
            }
        ]);

        var actualAgeGroups;
        tp.getGroups('age'/*, params*/).then(function(groups){
            actualAgeGroups = groups;
        });
        $rootScope.$digest();

        expect(actualAgeGroups).toEqual([
            {
                value: 27,
                data: [
                    {name: "Jacob", age: 27, role: 'Administrator'},
                    {name: "Jacob", age: 27, role: 'User'},
                    {name: "Jacob", age: 27, role: 'User'},
                    {name: "Jacob", age: 27, role: 'User'}
                ]
            },
            {
                value: 29,
                data: [
                    {name: "Nephi", age: 29, role: 'Moderator'},
                    {name: "Nephi", age: 29, role: 'Moderator'},
                    {name: "Nephi", age: 29, role: 'User'},
                    {name: "Nephi", age: 29, role: 'User'}
                ]
            },
            {
                value: 34,
                data: [
                    {name: "Enos", age: 34, role: 'User'},
                    {name: "Enos", age: 34, role: 'User'},
                    {name: "Enos", age: 34, role: 'Moderator'},
                    {name: "Enos", age: 34, role: 'User'}
                ]
            },
            {
                value: 43,
                data: [
                    {name: "Tiancum", age: 43, role: 'Administrator'},
                    {name: "Tiancum", age: 43, role: 'User'},
                    {name: "Tiancum", age: 43, role: 'Moderator'},
                    {name: "Tiancum", age: 43, role: 'User'}
                ]
            },{
                value: 50,
                data: [
                    {name: "Moroni", age: 50, role: 'Administrator'}
                ]
            }
        ]);
    }));

    it('ngTableParams test defaults', inject(function ($q, ngTableDefaults) {
        ngTableDefaults.params = {
            count: 2
        };
        ngTableDefaults.settings = {
            counts: []
        };
        var tp = new NgTableParams();

        expect(tp.count()).toEqual(2);
        expect(tp.page()).toEqual(1);

        var settings = tp.settings();
        expect(settings.counts.length).toEqual(0);
        expect(settings.interceptors.length).toEqual(0);
        expect(settings.filterDelay).toEqual(750);

        ngTableDefaults.settings.interceptors = [ { response: angular.identity }];
        tp = new NgTableParams();
        expect(tp.settings().interceptors.length).toEqual(1);
    }));

    describe('hasFilter', function(){
        var tp;

        beforeEach(inject(function(){
            tp = new NgTableParams({}, {});
        }));

        it('should return false for an empty filter object', function(){
            tp.filter({});
            expect(tp.hasFilter()).toBe(false);
        });

        it('should return true for when filter has a field with a significant value', function(){
            tp.filter({ a: 'b' });
            expect(tp.hasFilter()).toBe(true);

            tp.filter({ a: 0 });
            expect(tp.hasFilter()).toBe(true);
        });

        it('should return false when filter only has insignificant field values', function(){
            tp.filter({ a: '' });
            expect(tp.hasFilter()).toBe(false);

            tp.filter({ a: null });
            expect(tp.hasFilter()).toBe(false);

            tp.filter({ a: undefined });
            expect(tp.hasFilter()).toBe(false);

            tp.filter({ a: undefined, b: '', c: undefined });
            expect(tp.hasFilter()).toBe(false);

            //tp.filter({ a: NaN });
            //expect(tp.hasFilter()).toBe(false);
        });
    });

    describe('isDataReloadRequired', function(){
        var tp;

        beforeEach(inject(function(){
            tp = createNgTableParams();
        }));

        it('should return true after construction', function(){
            expect(tp.isDataReloadRequired()).toBe(true);
        });

        it('should return false once reload called after construction', function(){
            tp.reload();
            // note: we don't have to wait for the getData promise to be resolved before considering reload
            // to be unnecessary - that's why we're not having to run a $digest
            expect(tp.isDataReloadRequired()).toBe(false);
        });

        it('should return true when getData fails', inject(function($q){
            tp.settings({ getData: function(){
                return $q.reject('bad response');
            }});
            tp.reload();
            scope.$digest();
            expect(tp.isDataReloadRequired()).toBe(true);
        }));

        it('should detect direct changes to parameters', inject(function($q){
            // given
            tp.reload();
            scope.$digest();
            expect(tp.isDataReloadRequired()).toBe(false); // checking assumptions

            // when
            tp.filter().newField = 99;
            expect(tp.isDataReloadRequired()).toBe(true);
        }));

        it('should return true until changed parameters have been reloaded', function(){
            // given
            tp.reload();
            scope.$digest();

            // when, then...
            verifyIsDataReloadRequired(function(){
                tp.filter({ age: 1});
            });
            verifyIsDataReloadRequired(function(){
                tp.page(55);
            });
            verifyIsDataReloadRequired(function(){
                tp.sorting({ age: 'desc'});
            });
            verifyIsDataReloadRequired(function(){
                tp.count(100);
            });
        });

        it('should return false when parameters "touched" but not modified', function(){
            // given
            tp.filter({ age: 1});
            tp.reload();
            scope.$digest();

            // when, then...
            tp.filter({ age: 1});
            expect(tp.isDataReloadRequired()).toBe(false);
        });

        it('should return true when new settings data array supplied', function(){
            // given
            tp.reload();
            scope.$digest();

            verifyIsDataReloadRequired(function(){
                tp.settings({ data: [11,22,33]});
            });
        });

        it('should return true when existing settings data array is unset', function(){
            // given
            tp = createNgTableParams({ data: [1,2,3]});
            tp.reload();
            scope.$digest();

            verifyIsDataReloadRequired(function(){
                tp.settings({ data: null});
            });
        });

        it('status should not change when settings called without a data array', function(){
            // given
            tp = createNgTableParams({ data: [1,2,3]});
            tp.reload();
            scope.$digest();

            // when, then...
            tp.settings({ total : 100 });
            expect(tp.isDataReloadRequired()).toBe(false);
        });

        function verifyIsDataReloadRequired(modifer){
            modifer();
            expect(tp.isDataReloadRequired()).toBe(true);
            tp.reload();
            scope.$digest();
            expect(tp.isDataReloadRequired()).toBe(false);
        }
    });

    describe('hasFilterChanges', function(){
        var tp;

        beforeEach(inject(function(){
            tp = createNgTableParams();
        }));

        it('should return true after construction', function(){
            expect(tp.hasFilterChanges()).toBe(true);
        });

        it('should return false once reload called after construction', function(){
            tp.reload();
            // note: we don't have to wait for the getData promise to be resolved before considering reload
            // to be unnecessary - that's why we're not having to run a $digest
            expect(tp.hasFilterChanges()).toBe(false);
        });

        it('should return true when getData fails', inject(function($q){
            tp.settings({ getData: function(){
                return $q.reject('bad response');
            }});
            tp.reload();
            scope.$digest();
            expect(tp.hasFilterChanges()).toBe(true);
        }));

        it('should detect direct changes to filters', inject(function($q){
            // given
            tp.reload();
            scope.$digest();
            expect(tp.hasFilterChanges()).toBe(false); // checking assumptions

            // when
            tp.filter().newField = 99;
            expect(tp.hasFilterChanges()).toBe(true);
        }));

        it('should return true until changed filters have been reloaded', function(){
            // given
            tp.reload();
            scope.$digest();

            // when, then...
            tp.filter({ age: 1});
            expect(tp.hasFilterChanges()).toBe(true);
            tp.reload();
            scope.$digest();
            expect(tp.hasFilterChanges()).toBe(false);
        });

        it('should return false when filters "touched" but not modified', function(){
            // given
            tp.filter({ age: 1});
            tp.reload();
            scope.$digest();

            // when, then...
            tp.filter({ age: 1});
            expect(tp.hasFilterChanges()).toBe(false);
        });

        it('status should not change just because new settings data array supplied', function(){
            // given
            tp.reload();
            scope.$digest();

            // when, then...
            tp.settings({ data: [11,22,33]});
            expect(tp.hasFilterChanges()).toBe(false);
        });

    });

    describe('backwards compatibility shim', function(){

        it('shim should supply getData original arguments', inject(function(ngTableGetDataBcShim){
            // given
            var callCount = 0;
            var adaptedFn = ngTableGetDataBcShim(originalGetDataFn);

            // when
            var tableParams = new NgTableParams({}, {});
            adaptedFn(tableParams);

            // then
            expect(callCount).toBe(1);

            function originalGetDataFn($defer, params){
                callCount++;
                expect($defer).toBeDefined();
                expect($defer.resolve).toBeDefined();
                expect(params).toBeDefined();
                expect(params).toEqual(jasmine.any(NgTableParams));
            }

        }));

        it('shim should return the getData "$defer" promise', inject(function(ngTableGetDataBcShim){
            // given
            var callCount = 0;
            var adaptedFn = ngTableGetDataBcShim(originalGetDataFn);

            // when
            var tableParams = new NgTableParams({}, {});
            var results = adaptedFn(tableParams);

            // then
            expect(results).toBeDefined();
            expect(results.then).toBeDefined();
            results.then(function(data){
                expect(data.length).toBe(3);
            });
            scope.$digest();

            function originalGetDataFn($defer/*, params*/){
                $defer.resolve([1,2,3]);
            }
        }));

        it('shim should return the data', inject(function(ngTableGetDataBcShim){
            // given
            var callCount = 0;
            var adaptedFn = ngTableGetDataBcShim(originalGetDataFn);

            // when
            var tableParams = new NgTableParams({}, {});
            var results = adaptedFn(tableParams);

            // then
            expect(results).toBeDefined();
            expect(results).toEqual([1,2,3]);

            function originalGetDataFn(/*$defer, params*/){
                return [1,2,3];
            }
        }));

        it('shim should be applied when getData function supplied has more than one parameter', function(){
            // given
            var tp = createNgTableParams({ getData: originalGetDataFn});

            // when
            var dataFetched = tp.reload();

            // then
            var actualData;
            dataFetched.then(function(data){
                actualData = data;
            });
            scope.$digest();
            expect(actualData).toEqual([1,2,3]);

            function originalGetDataFn($defer, params){
                params.total(3);
                $defer.resolve([1,2,3]);
            }
        });

        it('shim should NOT be applied when getData has new signature', function(){
            // given
            var tp = createNgTableParams({ getData: newGetDataFn});

            // when
            var dataFetched = tp.reload();

            // then
            var actualData;
            dataFetched.then(function(data){
                actualData = data;
            });
            scope.$digest();
            expect(actualData).toEqual([1,2,3]);

            function newGetDataFn(params){
                params.total(3);
                return [1,2,3];
            }
        });
    });

    describe('interceptors', function(){

        it('can register interceptor', function(){
            var interceptor = { response: angular.identity };
            var tp = createNgTableParams({ interceptors: [interceptor]});
            expect(tp.settings().interceptors).toEqual([interceptor]);
        });

        it('can register multiple interceptor', function(){
            var interceptors = [{ response: angular.identity }, { response: angular.identity }];
            var tp = createNgTableParams({ interceptors: interceptors});
            expect(tp.settings().interceptors).toEqual(interceptors);
        });

        it('can register interceptors after NgTableParams created', function(){
            var interceptor = { response: angular.identity };
            var interceptor2 = { response: angular.identity };
            var tp = createNgTableParams({ interceptors: [interceptor]});
            var interceptors = tp.settings().interceptors.concat([interceptor2]);
            tp.settings({ interceptors: interceptors});
            expect(tp.settings().interceptors).toEqual(interceptors);
        });

        describe('one response interceptor', function(){

            it('should receive response from call to getData', function(){
                // given
                var interceptor = {
                    response: function(/*data, params*/){
                        this.hasRun = true;
                    }
                };
                var tp = createNgTableParams({ interceptors: [interceptor]});

                // when
                tp.reload();
                scope.$digest();

                // then
                expect(interceptor.hasRun).toBeTruthy();
            });

            it('should be able to modify data returned by getData', function(){
                // given
                var interceptor = {
                    response: function(data/*, params*/){
                        data.forEach(function(item){
                            item.modified = true;
                        });
                        return data;
                    }
                };
                var tp = createNgTableParams({ interceptors: [interceptor], getData: function(){
                    return [{}, {}];
                }});

                // when
                var actualData;
                tp.reload().then(function(data){
                    actualData = data;
                });
                scope.$digest();

                // then
                expect(actualData).toEqual([{ modified: true }, { modified: true }]);
            });

            it('should be able to replace data returned by getData', function(){
                // given
                var interceptor = {
                    response: function(data/*, params*/){
                        return data.map(function(item){
                            return item * 2;
                        });
                    }
                };
                var tp = createNgTableParams({ interceptors: [interceptor], getData: function(){
                    return [2, 3];
                }});

                // when
                var actualData;
                tp.reload().then(function(data){
                    actualData = data;
                });
                scope.$digest();

                // then
                expect(actualData).toEqual([4, 6]);
            });

            it('should be able to access tableParams supplied to getData', function(){
                // given
                var interceptor = {
                    response: function(data, params){
                        params.total(data.total);
                        return data.results;
                    }
                };
                var tp = createNgTableParams({ interceptors: [interceptor], getData: function(){
                    return { results: [1,2,3], total: 3};
                }});

                // when
                var actualData;
                tp.reload().then(function(data){
                    actualData = data;
                });
                scope.$digest();

                // then
                expect(actualData).toEqual([1,2,3]);
                expect(tp.total()).toEqual(3);
            });
        });

        describe('one responseError interceptor', function(){

            it('should receive rejections from getData', inject(function($q){
                // given
                var interceptor = {
                    responseError: function(reason/*, params*/){
                        this.actualReason = reason;
                    }
                };
                var tp = createNgTableParams({
                    interceptors: [interceptor],
                    getData: function(/*params*/){
                        return $q.reject('BANG!');
                    }
                });

                // when
                tp.reload();
                scope.$digest();

                // then
                expect(interceptor.actualReason).toBe('BANG!');
            }));

            it('should NOT receive errors from getData', function(){
                // given
                var interceptor = {
                    responseError: function(/*reason, params*/){
                        this.hasRun = true;
                    }
                };
                var tp = createNgTableParams({
                    interceptors: [interceptor],
                    getData: function(/*params*/){
                        throw new Error('BANG!');
                    }
                });

                // when, then
                expect(tp.reload).toThrow();
                expect(interceptor.hasRun).toBeFalsy();
            });

            it('should be able to modify reason returned by getData', inject(function($q){
                // given
                var interceptor = {
                    responseError: function(reason/*, params*/){
                        reason.code = 400;
                        return $q.reject(reason);
                    }
                };
                var tp = createNgTableParams({
                    interceptors: [interceptor],
                    getData: function(/*params*/){
                        return $q.reject({ description: 'crappy data'});
                    }
                });

                // when
                var actualReason;
                tp.reload().catch(function(reason){
                    actualReason = reason;
                });
                scope.$digest();

                // then
                expect(actualReason.code).toBe(400);
                expect(actualReason.description).toBe('crappy data');
            }));

            it('should be able to replace reason returned by getData', inject(function($q){
                // given
                var interceptor = {
                    responseError: function(/*reason, params*/){
                        return $q.reject('Cancelled by user');
                    }
                };
                var tp = createNgTableParams({
                    interceptors: [interceptor],
                    getData: function(/*params*/){
                        return $q.reject('BANG!');
                    }
                });

                // when
                var actualReason;
                tp.reload().catch(function(reason){
                    actualReason = reason;
                });
                scope.$digest();

                // then
                expect(actualReason).toBe('Cancelled by user');
            }));

            it('should be able to access tableParams supplied to getData', function(){
                // given
                var interceptor = {
                    response: function(reason, params){
                        this.actualParams = params;
                    }
                };
                var tp = createNgTableParams({ interceptors: [interceptor]});

                // when
                var actualData;
                tp.reload();
                scope.$digest();

                // then
                expect(interceptor.actualParams).toBe(tp);
            });
        });

        describe('one response plus responseError interceptor', function(){

            it('should NOT call responseError on same interceptor whose response method fails', inject(function($q){
                // given
                var interceptor = {
                    response: function(/*data, params*/){
                        return $q.reject('BANG!');
                    },
                    responseError: function(reason/*, params*/){
                        this.hasRun = true;
                    }
                };
                var tp = createNgTableParams({
                    interceptors: [interceptor],
                    getData: function(/*params*/){
                        return [1,2,3];
                    }
                });

                // when
                tp.reload();
                scope.$digest();

                // then
                expect(interceptor.hasRun).toBeFalsy();
            }));
        });

        describe('multiple response interceptors', function(){

            it('should run interceptors in the order they were registered', function(){
                // given
                var callCount = 0;
                var interceptor = {
                    response: function(/*data, params*/){
                        this.sequence = callCount;
                        callCount++;
                    }
                };
                var interceptors = [interceptor, angular.copy(interceptor)];
                var tp = createNgTableParams({ interceptors: interceptors});

                // when
                tp.reload();
                scope.$digest();

                // then
                expect(interceptors[0].sequence).toBe(0);
                expect(interceptors[1].sequence).toBe(1);
            });

            it('results of one interceptor should be piped to the next validator', function(){
                // given
                var interceptor = {
                    response: function(data/*, params*/){
                        return data.map(function(item){
                            return item * 2;
                        });
                    }
                };
                var interceptor2 = {
                    response: function(data/*, params*/){
                        return data.map(function(item){
                            return item.toString() + '0';
                        });
                    }
                };
                var tp = createNgTableParams({ interceptors: [interceptor, interceptor2], getData: function(){
                    return [2, 3];
                }});

                // when
                var actualData;
                tp.reload().then(function(data){
                    actualData = data;
                });
                scope.$digest();

                // then
                expect(actualData).toEqual(['40', '60']);
            });
        });

        describe('multiple response and responseError interceptors', function(){

            it('responseError of next interceptor should receive failures from previous interceptor', inject(function($q){
                // given
                var badInterceptor = {
                    response: function(/*data, params*/){
                        return $q.reject('BANG!');
                    }
                };
                var nextInterceptor = {
                    responseError: function(/*reason, params*/){
                        this.hasRun = true;
                    }
                };
                var tp = createNgTableParams({ interceptors: [badInterceptor, nextInterceptor]});

                // when
                tp.reload();
                scope.$digest();

                // then
                expect(nextInterceptor.hasRun).toBe(true);
            }));

            it('should call next response interceptor when previous interceptor recovers from failure', inject(function($q){
                // given
                var badInterceptor = {
                    response: function(/*data, params*/){
                        return $q.reject('BANG!');
                    }
                };
                var recoveringInterceptor = {
                    responseError: function(/*reason, params*/){
                        return [8894,58];
                    }
                };
                var recoveredData;
                var nextInterceptor = {
                    response: function(data/*, params*/){
                        this.hasRun = true;
                        recoveredData = data;
                    }
                };
                var tp = createNgTableParams({ interceptors: [badInterceptor, recoveringInterceptor, nextInterceptor]});

                // when
                tp.reload();
                scope.$digest();

                // then
                expect(nextInterceptor.hasRun).toBe(true);
                expect(recoveredData).toEqual([8894,58]);
            }));
        });
    });

    describe('events', function(){

        var actualEventArgs,
            actualPublisher,
            fakeTableParams,
            ngTableEventsChannel;

        beforeEach(inject(function(_ngTableEventsChannel_){
            ngTableEventsChannel = _ngTableEventsChannel_;
            fakeTableParams = {};
            actualPublisher = undefined;
            actualEventArgs = undefined;
        }));

        function getSubscriberCount(){
            var allEventNames = Object.keys($rootScope.$$listenerCount);
            var ngTableEvents = allEventNames.filter(function(event){
                return event.indexOf('ngTable:') === 0;
            });
            return ngTableEvents.reduce(function(result, event){
                result += $rootScope.$$listenerCount[event];
                return result;
            }, 0);
        }

        describe('general pub/sub mechanics', function(){

            var supportedEvents = ['DatasetChanged', 'AfterReloadData', 'PagesChanged', 'AfterCreated'];

            it('should be safe to publish event when no subscribers', function () {

                function test(event) {
                    ngTableEventsChannel['publish' + event](fakeTableParams);
                }

                supportedEvents.forEach(test);
            });

            it('publishing event should notify registered subscribers (one)', function(){

                function test(event){
                    // given
                    var cbCount = 0;
                    ngTableEventsChannel['on' + event](function(){
                        cbCount++;
                    });

                    // when
                    ngTableEventsChannel['publish' + event](fakeTableParams);

                    // then
                    expect(cbCount).toBe(1);
                }

                supportedEvents.forEach(test);
            });

            it('publishing event should notify registered subscribers (multiple)', function(){

                function test(event){
                    // given
                    var cb1Count = 0;
                    ngTableEventsChannel['on' + event](function(){
                        cb1Count++;
                    });
                    var cb2Count = 0;
                    ngTableEventsChannel['on' + event](function(){
                        cb2Count++;
                    });

                    // when
                    ngTableEventsChannel['publish' + event](fakeTableParams);

                    // then
                    expect(cb1Count).toBe(1);
                    expect(cb2Count).toBe(1);
                }

                supportedEvents.forEach(test);
            });

            it('subscriber should be able to unregister their callback', function(){

                function test(event){
                    // given
                    var cbCount = 0;
                    var subscription = ngTableEventsChannel['on' + event](function(){
                        cbCount++;
                    });
                    ngTableEventsChannel['publish' + event](fakeTableParams);
                    expect(cbCount).toBe(1); // checking assumptions
                    expect(getSubscriberCount()).toBe(1); // checking assumptions
                    cbCount = 0; // reset

                    // when
                    subscription(); // unsubscribe
                    ngTableEventsChannel['publish' + event](fakeTableParams);

                    // then
                    expect(cbCount).toBe(0);
                    expect(getSubscriberCount()).toBe(0);
                }

                supportedEvents.forEach(test);
            });

            it('subscriber should be able specify the scope to receive events', function(){

                // this is useful as it allows all subscriptions to be removed by calling $destroy on that scope

                function test(event){
                    // given
                    var childScope = $rootScope.$new();
                    var cbCount = 0;
                    ngTableEventsChannel['on' + event](function(){
                        cbCount++;
                    }, childScope);

                    // when, then
                    ngTableEventsChannel['publish' + event](fakeTableParams);
                    expect(cbCount).toBe(1);

                    cbCount = 0; // reset

                    // when, then
                    childScope.$destroy();
                    ngTableEventsChannel['publish' + event](fakeTableParams);

                    // then
                    expect(cbCount).toBe(0);
                }

                supportedEvents.forEach(test);
            });

            it('should not notify subscribers who have filter out the publisher', function(){

                function test(event){
                    // given
                    var cbCount = 0;
                    ngTableEventsChannel['on' + event](function(){
                        cbCount++;
                    }, function(publisher){
                        return publisher === fakeTableParams;
                    });

                    // when
                    ngTableEventsChannel['publish' + event](fakeTableParams);
                    var anoParams = {};
                    ngTableEventsChannel['publish' + event](anoParams);

                    // then
                    expect(cbCount).toBe(1);
                }

                supportedEvents.forEach(test);
            });

            it('should not notify subscribers who have filter not to receive event based on arg values', function(){

                function test(event){
                    // given
                    var cbCount = 0;
                    ngTableEventsChannel['on' + event](function(){
                        cbCount++;
                    }, function(publisher, arg1){
                        return arg1 === 1;
                    });

                    // when
                    ngTableEventsChannel['publish' + event](fakeTableParams, 'cc');
                    ngTableEventsChannel['publish' + event](fakeTableParams, 1);

                    // then
                    expect(cbCount).toBe(1);
                }

                supportedEvents.forEach(test);
            });

            it('should support a shorthand for subscribers to receive events from specific NgTableParams instance', function () {

                function test(event) {
                    // given
                    var cbCount = 0;
                    ngTableEventsChannel['on' + event](function () {
                        cbCount++;
                    }, fakeTableParams);

                    // when
                    ngTableEventsChannel['publish' + event](fakeTableParams);
                    var anoParams = {};
                    ngTableEventsChannel['publish' + event](anoParams);

                    // then
                    expect(cbCount).toBe(1);
                }

                supportedEvents.forEach(test);
            });

            it('publisher should be supplied to subscriber callback', function(){

                function test(event){
                    // given
                    var cbCount = 0;
                    ngTableEventsChannel['on' + event](function(params){
                        actualPublisher = params;
                    });

                    // when
                    ngTableEventsChannel['publish' + event](fakeTableParams);

                    // then
                    expect(actualPublisher).toBe(fakeTableParams);
                }

                supportedEvents.forEach(test);
            });

            it('remaining event args should be supplied to subscriber callback', function(){

                function test(event){
                    // given
                    ngTableEventsChannel['on' + event](function(params/*, ...args*/){
                        actualPublisher = params;
                        actualEventArgs = _.rest(arguments);
                    });

                    // when
                    var arg1 = [1, 2];
                    var arg2 = [1];
                    ngTableEventsChannel['publish' + event](fakeTableParams, arg1, arg2);

                    // then
                    expect(actualEventArgs).toEqual([arg1, arg2]);
                }

                supportedEvents.forEach(test);
            });

            it('subscribers should never receive events from null instance of tableParams', function(){

                function test(event){
                    // given
                    var cbCount = 0;
                    ngTableEventsChannel['on' + event](function(params/*, ...args*/){
                        cbCount++;
                    });

                    // when
                    fakeTableParams.isNullInstance = true;
                    ngTableEventsChannel['publish' + event](fakeTableParams);

                    // then
                    expect(cbCount).toEqual(0);
                }

                supportedEvents.forEach(test);
            });

        });

        describe('afterCreated', function(){

            it('should fire when a new NgTableParams has been constructed', function(){
                // given
                ngTableEventsChannel.onAfterCreated(function(params){
                    actualPublisher = params;
                });

                // when
                var params = createNgTableParams();

                // then
                expect(actualPublisher).toBe(params);
            });
        });

        describe('afterReloadData', function(){

            it('should fire when a reload completes', function(){
                // given
                ngTableEventsChannel.onAfterReloadData(function(params, newVal, oldVal){
                    actualPublisher = params;
                    actualEventArgs = [newVal, oldVal];
                });
                var newDatapage = [1, 5, 6];
                var params = createNgTableParams({ getData: function(){
                    return newDatapage;
                }});

                // when
                params.reload();
                scope.$digest();

                // then
                expect(actualPublisher).toBe(params);
                expect(actualEventArgs).toEqual([newDatapage, []]);
            });

            it('should fire on reload even if datapage remains the same array', function(){
                // given
                var callCount = 0;
                ngTableEventsChannel.onAfterReloadData(function(/*params, newVal, oldVal*/){
                    callCount++;
                });
                var dataPage = [1,2,3];
                var params = createNgTableParams({ getData: function(){
                    return dataPage;
                }});

                // when
                params.reload();
                scope.$digest();
                params.reload();
                scope.$digest();

                // then
                expect(callCount).toBe(2);
            });
        });

        describe('pagesChanged', function(){

            it('should fire when a reload completes', function(){
                // given
                ngTableEventsChannel.onPagesChanged(function(params, newVal, oldVal){
                    actualPublisher = params;
                    actualEventArgs = [newVal, oldVal];
                });
                var params = createNgTableParams({ count: 5 }, { counts: [5,10], data: [1,2,3,4,5,6]});

                // when
                params.reload();
                scope.$digest();

                // then
                var expectedPages = params.generatePagesArray(params.page(), params.total(), params.count());
                expect(expectedPages.length).toBeGreaterThan(0); // checking assumptions
                expect(actualEventArgs).toEqual([expectedPages, undefined]);
            });

            it('should fire when a reload completes - no data', function(){
                // given
                ngTableEventsChannel.onPagesChanged(function(params, newVal, oldVal){
                    actualPublisher = params;
                    actualEventArgs = [newVal, oldVal];
                });
                var params = createNgTableParams({ count: 5 }, { counts: [5,10], data: []});

                // when
                params.reload();
                scope.$digest();

                // then
                expect(actualEventArgs).toEqual([[], undefined]);
            });

            it('should fire when a reload completes (multiple)', function(){
                // given
                var callCount = 0;
                ngTableEventsChannel.onPagesChanged(function(/*params, newVal, oldVal*/){
                    callCount++;
                });
                var params = createNgTableParams({ count: 5 }, { counts: [5,10], data: [1,2,3,4,5,6]});

                // when
                params.reload();
                scope.$digest();
                params.page(2); // trigger a change to pages data structure
                params.reload();
                scope.$digest();

                // then
                expect(callCount).toBe(2);
            });

            it('should not fire on reload when pages remain the same', function(){
                // given
                var callCount = 0;
                ngTableEventsChannel.onPagesChanged(function(/*params, newVal, oldVal*/){
                    callCount++;
                });
                var params = createNgTableParams({ count: 5 }, { counts: [5,10], data: [1,2,3,4,5,6]});
                params.reload();
                scope.$digest();

                // when
                params.reload();
                scope.$digest();

                // then
                expect(callCount).toBe(1);
            });
        });

        describe('datasetChanged', function(){

            it('should fire when a initial dataset is supplied as a settings value', function(){
                // given
                ngTableEventsChannel.onDatasetChanged(function(params, newVal, oldVal){
                    actualPublisher = params;
                    actualEventArgs = [newVal, oldVal];
                });

                // when
                var initialDs = [5, 10];
                var params = createNgTableParams({ data: initialDs});

                // then
                expect(actualPublisher).toBe(params);
                expect(actualEventArgs).toEqual([initialDs, null]);
            });

            it('should fire when a new dataset is supplied as a settings value', function(){
                // given
                var initialDs = [1, 2];
                ngTableEventsChannel.onDatasetChanged(function(params, newVal, oldVal){
                    actualPublisher = params;
                    actualEventArgs = [newVal, oldVal];
                });
                var params = createNgTableParams({ data: initialDs});

                // when
                var newDs = [5, 10];
                params.settings({ data: newDs});

                // then
                expect(actualPublisher).toBe(params);
                expect(actualEventArgs).toEqual([newDs, initialDs]);
            });

            it('should fire when a dataset is removed from settings value', function(){
                // given
                var initialDs = [1, 2];
                ngTableEventsChannel.onDatasetChanged(function(params, newVal, oldVal){
                    actualPublisher = params;
                    actualEventArgs = [newVal, oldVal];
                });
                var params = createNgTableParams({ data: initialDs});

                // when
                var newDs = null;
                params.settings({ data: newDs});

                // then
                expect(actualPublisher).toBe(params);
                expect(actualEventArgs).toEqual([newDs, initialDs]);
            });

            it('should NOT fire when the same data array is supplied as a new settings value', function(){
                // given
                var callCount = 0;
                var initialDs = [1, 2];
                ngTableEventsChannel.onDatasetChanged(function(/*params, newVal, oldVal*/){
                    callCount++;
                });
                var params = createNgTableParams({ data: initialDs});

                // when
                params.settings({ data: initialDs});

                // then
                expect(callCount).toBe(1);
            });

            it('settings().data on publisher should reference the new dataset', function(){
                var initialDs = [1, 2];
                var newDs = [1, 2, 3];
                var params = createNgTableParams({ data: initialDs});
                ngTableEventsChannel.onDatasetChanged(function(params, newVal/*, oldVal*/){
                    expect(params.settings().data).toBe(newVal);
                });
                params.settings({ data: newDs});
            });
        });
    })
});

redpajama_set_name: RedPajamaGithub


text:
Home Issue 23 Hands-on tourism boss in bid for mayor
Hands-on tourism boss in bid for mayor
Erwin Chlanda
By ERWIN CHLANDA
A man who came to town as a printer, a "solitary" occupation as he describes it, switched to tourism because it's more fun to be with people looking for a good time.
Now Patrick Bedford is running a significant business, Emu Run, with 15 staff and 15 vehicles ranging from three large coaches to several mid-size ones to 4WDs, and two accommodation houses, including the hostel in Muehler Street where he stayed when he first arrived 16 years ago.
He is also the president of Tourism Central Australia, which has 430 members. He is pictured above during a promotion in the Mall of the Mereenie loop road sealing in July last year.
And today he announced his bid for Mayor (and councillor) in next month's local government elections.
He says he wants to be a player in this critical time for the town, whose major industry, because of Covid, ricochets between plenty of staff and few customers, or lots of customers and not enough staff, with a painful changeover time of some six weeks each time.
There are mixed messages confusing the industry and customers alike, he says.
Emu Run operates in the West MacDonnells and the Lasseter region.
But the town plays a major role: "We need to re-vitalise the CBD," Mr Bedford says.
"The Mall isn't much more than a couple of coffee shops. We need families to re-engage with it. It needs a playground, a water park."
He has four children, aged from five to 13.
Above all, the rate of vaccinations will need to be boosted. General practitioners should have been involved much sooner, to achieve an 80% full vaccination rate.
The News will publish a comprehensive interview with Mr Bedford later this week.
mayor election
patrick Bedford
Previous articleMassive water allocation scandal takes new turn
Next articleSingleton water gift: Back to the drawing board
https://alicespringsnews.com.au
The Gap isn't closing, the question is why
Centrecorp expands into construction industry
Evelyne Roullet 28 July 2021 At 6:49 pm
Good on you, Patrick, for putting your hand up.
Be Mayor or councillor, with your stamina, your work ethics and your Irish sense of humour, you will achieve.
Pseudo Guru 28 July 2021 At 8:16 pm
A good choice to "Make Alice Springs Great Again".

redpajama_set_name: RedPajamaCommonCrawl


Before I moved to London, natives told me that no real Londoner spends time in Central London. "Oh it's for tourists," they would insist. I could not see how that was possible. After all, Johnson's adage is true: "When a man is tired of London, he is tired of life; for there is in London all that life can afford." The humming hub of central London, The West End, is teeming with life and buzz and character. We spent many a weekend for what seemed like the first few years of our existence in the capital exploring vintage stores and vegetarian restaurants, cocktail bars and coffee shops that secreted cool.
But hey, you discover a beautiful area like Hackney, you buy a nice place, decorate it with reclaimed, exposed brick, distressed g plan and suddenly you've carved a corner of this city for yourself outside of which you rarely have to roam. You think, is there really any point in squeezing, sardine-like, onto the tube to meander around streets immersing oneself in the ubiquitous commercial glitz of the chain store on the Great British High Street, only to compress your body mass once again, bracing yourself for the depths of the Central Line on the way home?
The Missus and I braved it anyway on Tuesday, gluttons for punishment that we are. I had the day off for the Jewish holiday of Shmini Atzeret and we seemed to find ourselves in possession of that rarest of commodities: free time.
So head into the West End we did and surprise surprise, I would rate the journey as okay to moderately pleasant, walking around W1 and environs therein reminded me more of a flaneuristic stroll than a claustrophobic squeeze and most joyously surprising of all was that as we were walking back towards Holborn, hankering for a cup of joe and eager to avoid the blandness of Costa and the burnt yet saccharine putridity of a beverage from a Seattle based chain that will remain unnamed, we stumbled upon Salt (pictured above), a lovely little place and a rare find in touristy central London. Salt is stylishly designed, has a great menu, and a lovely and welcoming atmosphere. It feels much more contemporary East End/Hackney than West End/Covent Garden partly because of the choices made in arranging the sleek and aesthetically pleasing interior and partly because of their choice of coffee — the eminently delectable Square Mile Roasters based in (where else?) the East End, bohemian Bethnal Green to be precise. Employees were cordial and the coffee was smooth, subtle and well crafted as is in evidence below. Tables were high, oblong and affixed to corners and walls, enjoyed atop chic stools from East London Furniture with lattes and flatties served in charmingly mismatched china and glasses.
Big deal. It's a coffee shop. Doppio a dozen. Why am I so impressed? I'm impressed because you rarely find an enticing independent establishment that's able to peep out from below brash and bulky elbows of the crowded together conglomerations of corporate cappuccino-serving froth factories in the center of this grand metropolis. Generally speaking, the options for tourists (Yanks and otherwise) range from Nero (bland) to Pret (organic bland) to the aforementioned Seattle-based chain (a taste of home bland) with not much in between. In the East End, you find that enterprising, libertarian spirit from Roman Road Market clear across to Murder Mile, but giving tourists in the ole Covent Garden a taste of high quality espresso for moderately low prices? This place gets kudos for bravery, ambiance, and caliber of product.
So, visiting compatriots, when you are around the market or The Actors Church or The Transport Museum and you want a delicious lunch at a decent price followed by elation-inducing double espresso, this place is not more than a stone's throw and worth making the time to find.


Our double capacity Right To Know Compliance Centers include a red polystyrene board, two binder racks and two MSDS binders. Centers are available in English (2010DB with 2023 MSDS Binders) or Spanish (2010DBSP with 2026 Bilingual MSDS Binders). Center # RK208A is also available in English with two binder inserts (BR801B). Center size is 20"H x 29"W x 4 1/2"D.
Brady 2023 1-1/2" Diameter Rings, Polyethylene, Red On Yellow Color Standard MSDS Binder, Legend "Material Safety Data Sheets"
Brady 2023/45989 standard MSDS binder 1-1/2" ring,1-1/2" diameter rings hold 275-300 sheets, 21/2" diameter ring holds 400-500 sheets and 3" diameter ring hold 600 sheets. Size is 1-1/2" diameter rings. Legend is "MATERIAL SAFETY DATA SHEETS", color is red on yellow, , material is polyethylene.
Brady 45980/2014 binder holders, binder holder size is 9" height, 14" width, 4-1/2" depth, color is yellow, application wall mount, material is pvc coated steel.
Post this 180-degree Projection Sign above your Right to Know Center (sold separately) where you store Material Safety Data Sheets in the safety rack. The repeated message of SDS can be viewed from front and sides. Sign is made of thick high-impact plastic.
Brady 2025 3" Diameter Rings, Polyethylene, Red On Yellow Color Standard MSDS Binder, Legend "Material Safety Data Sheets"
Brady 2025/45991 standard MSDS binder 3" ring,1-1/2" diameter rings hold 275-300 sheets, 21/2" diameter ring holds 400-500 sheets and 3" diameter ring hold 600 sheets. Size is 3" diameter rings. Legend is "MATERIAL SAFETY DATA SHEETS", color is red on yellow, material is polyethylene.
Copyright © Wholesalion.com 2019 - The Best Prices On Msds Information Center Online.


Guided deer hunting greatly increases the likelihood of grassing a great trophy.
Don Caswell says hunting guides have the skills, experience and access to good country needed for success, but it is not always easy.
"It never rains in July," I said loudly over the noise, but the joke had worn thin and nobody responded. The four of us stood, cold and sodden, looking out at the torrential rain. The noise on the overhead galvanised iron roof was near deafening.
The promise of a hot lunch had lured us back to base in an effort to try and warm ourselves. We had been out on the quads since before dawn. Cold drizzle interspaced with heavy downpours had been the order of the morning, just like the previous days.
We had father and son Kiwi hunters, Tony and Nathan, seeking a trophy Chital stag each. Tony had conceded first shot to his son Nathan and the young fellow had dropped a good stag on the second morning, after a great stalk in drizzling rain.
The weather had gotten progressively worse since then, and despite many promising stalks, we had not yet been able to find a trophy class animal for Tony. He was an experienced and disciplined deer stalker and had passed up a couple of stags that a less discerning hunter may well have pulled the trigger on.
The country was saturated and all the creeks were running bankers, greatly limiting our avenues of opportunity. After hot showers and a change into our least wet clothes we sat down to a big, hearty hot meal, cooked up by guide Tello. Everyone's' humour improved with that and a few big cups of steaming hot tea to wash it down.
Our Kiwi clients pondered aloud whether they were really in Queensland at all. The weather was much more reminiscent of Fiord Land back in New Zealand and, as we all knew, it was not supposed to rain in Queensland in July. We dwelled awhile over lunch; nobody seemed enthusiastic to go back out in the cold rain.
Tello broke the spell though, and with his typical dedication, had us back out in the rain in short order. It was a couple of hours into the night when we finally got back, unsuccessful once again. The rain had been unrelenting and we had pushed as far out as we could. The trip home had been a long and difficult one with rising creeks and many kilometres of greasy, black soil tracks to fight the quads through.
Shivering, saturated through from head to foot, and liberally plastered with black mud, we must have looked a site as we dragged ourselves back into the quarters. Once again, hot showers and a big, hot meal restored our spirits.
The next day was our Kiwis' last day and we had yet to get Tony onto an acceptable trophy. On top of that was the looming problem of getting our clients out and back to Townsville airport for their flight home. All access roads were cut by creeks running metres above their normal levels.
Overnight the heavy rain eased off. When Tello roused us all from our beds for another pre-dawn start we were pleased to find light, misty rain rather than an ongoing torrential downpour. After a quick breakfast we reluctantly dragged on our wet, cold hunting gear. None of us even had dry socks and all clothing and boots were sodden and heavy. We rode the quads only a kilometre or so from the homestead, then set off on foot in the early morning mist at first light.
Nathan had elected to go along as observer and photographer of his Dad's hunt rather than take the opportunity to do some cull hunting with me, so the four of us set off, keen to get Tony his trophy on this, the last day of the hunt.
The normally dry gullies were still running with water, but now it was just a trickle, compared to the torrents of the last few days. Large deposits of sand and silt attested to how high the waters had risen. These newly formed sand banks also told a story of the game that had recently crossed them. There was plenty of fresh deer sign where stags and their harems had crossed the creek not long before.
Typically, we made short, slow advances and then spent extended periods glassing the surrounding bush, looking for deer. Tello has this technique mastered and the challenge, with some clients, is to restrict their eagerness to move forward too quickly, especially when a potential trophy stag has been spotted.
Apart from the challenge of finding a trophy animal, the other major aspect of a successful trophy hunt is knowing where all the other deer in the vicinity are. An eager and incautious approach on the trophy animal will often be spoilt by the alarm call of the old hind you failed to notice off to one side. So it is that a successful trophy stag hunt is generally based on a lot of glassing with binoculars.
After stalking slowly for an hour or so, there was a lengthier pause than normal as Tello seemed frozen with binoculars to his eyes for an inordinately long time, even for Tello! At his beckoning, Nathan and I very slowly and cautiously drifted up to join him and Tony. In the barest of whispers Tello told us he had spotted a likely looking trophy stag, bedded down behind a bush.
It took quite a bit of direction before we could finally see the stag ourselves, heavily screened by an intervening bush. Only a highly experienced and disciplined guide, like Tello, would have spotted that animal under the circumstances.
We discussed a game plan in hushed whispers. However, before we could start on the plan to flank the stag for a shot, more deer came drifting over the nearby ridge and blocked the intended path. What with the wind and scattering of nearby deer we had no option but freeze and remain motionless until the situation improved.
Well, the minutes dragged by, leading into hours. Tello and Tony had decided that this was the stag and they were prepared to wait him out rather than go off in the hope of finding something else. If you have never tried to remain perfectly still for any period of time then you will have no concept of how difficult that can be.
Muscles and joints ache and burn. Maddening itches and crawling insects have to be tolerated. Tickling throats cannot be relieved with a cough. If a movement is unavoidable it must be done with great slowness and care.
One consolation was that the mist slowly cleared as the morning developed and the light rain ceased as well. The sky, still overcast, nevertheless began to lighten and there was a hint that the sun was trying to re-exert itself over the land once more.
Finally, as midday approached, the deer all decided to move on. They were not alarmed, but as if to some silent signal, the various deer scattered through the bush all about us began to walk slowly off in the same direction. The trophy stag remained put for some time though and it was not until most of the other deer had moved off that he rose from his bed.
Tony was ready for the shot and the 270 Winchester boomed in the gully. As we walked up to the fallen stag the sun finally broke through the clouds and washed the land in pale, cloud-filtered light. We were all happy, but Tony was quite rightly elated. He had grassed a fine trophy Chital after days of hard and challenging hunting and the final stalk had been demanding of patience and perseverance as well.
Early the next morning I farewelled Tony and Nathan as Tello drove off on the journey to the airport. While he was dropping them off and collecting the next client I busied myself in restoring order to the camp and trying to dry out clothes and kit. There was no more rain and enough intermittent sunshine to achieve that reasonably well.
Tello made good time, despite the slippery dirt roads and still high creek crossings, and I was a little surprised when his vehicle pulled in around about 4PM with Clint, an Aussie deer hunter keen to get his first Chital.
After getting his gear unpacked, Tello took Clint to the range to test the sighting of his 300 Winchester Magnum. I had nothing better to do, so I tagged along as well. Clint fired three shots, all nicely on target to everyone's satisfaction. It was quite a nice afternoon and, as there was still an hour or so of daylight, we figured we would do a little glassing off the road, hoping to show Clint a few Chital before we began hunting in earnest the next day.
As we stood on the edge of the road, binoculars in hand, the property owners came by on their quads, returning from a day of repairing flood damaged fences. They stopped to meet Clint and have a chat for a while. Before they left they mentioned they had earlier seen a mob of pigs moving down the creek in our direction.
There was only half an hour of daylight left. Tello figured we could motor down to the nearby creek crossing and expect the pigs to arrive there just about right on dark. Clint may well get a chance to shoot a boar, without interfering with or jeopardising his chances of a trophy stag in the days to come. Once clients have taken their trophy, and have time up their sleeve, it is common practice to do some cull hunting of deer and shoot a few pigs as well. It was however unusual to start a trophy hunt by shooting secondary species first up.
We rode the quads a kilometre or two then parked, to walk the last half a kilometre down to the creek. We had only walked a few hundred metres when Tello signalled us to stop. Directly ahead of us, about 150 metres away, two big stags were brilliantly highlighted by the last rays of the setting sun. They were in the open, short-grassed country of the creek flood plain.
The two stags were feeding off the fruit of a lone shiny-apple tree. In that setting, in the fading pale gold light of the day, they were a sight to behold. Both seemed to have exceptional antlers too and displayed them nicely as they thrashed the overhead tree branches to shake down more fruit.
"They both look like keepers to me, but you are the expert here." I replied.
I stayed put behind a tree and watched the stalk. Tello and Clint moved forward carefully to close the distance to about 120 metres. After a few more minutes of careful scrutiny they decided on which of the two was their preferred target. Clint settled in, using a tree for a lean, and took the shot.
By the time we got back with the quads it was quite dark. Our usual hunting kit was back in camp, along with the camera gear, as we had started out with no expectation other than a few shots at the range. Luckily Clint had his mobile phone in his pocket, so we got some photos on that before Tello set about caping out the head in the light of a small pocket torch.
Even though Clint shot his trophy virtually the minute he arrived we still had an enjoyable four days of hunting with him. With the pressure off, so to speak, we explored obscure corners of the vast property, chasing pigs and wild dogs. I dropped Tello and Clint off well out on the track and they spent the best part of one day walking back to camp, hunting as they went. Along the way Clint shot a number of cull does and took the skins for tanning.
Those two, consecutive hunts neatly demonstrate the full spectrum of what you may expect on a guided trophy deer hunt. Sometimes it can be very demanding and sometimes ridiculously easy. Whether hard, easy or average you can expect your guide to find you some quality animals and help you to secure a memorable trophy. Along the way you will learn a lot about the finesse required to consistently find and stalk trophy deer, and have a thoroughly enjoyable hunt.
Since 1981 Don Caswell has been a freelance writer, photographer & illustrator. Don is the author of hunting stories and the provider of technical shooting information. Don an independent reviewer of hunting, shooting & outdoors products, in addition to being a blogger & webmaster with Facebook & Instagram presence. Don is also a senior writer for the Sporting Shooters Association of Australia (SSAA) and his articles appear regularly in their publications. This article was originally published in the SSAA in April 2014.


text:
Tagged: Nile
by Anders Camitz · Published November 22, 2019
Sweden Rock Festival presents 31 acts for 2020
Sweden Rock Festival has announced the first 31 acts that will play at the 2020 edition. The festival will be held on June 3rd-6th 2020 in Sölvesborg, south of Sweden. Tickets go on sale on Wednesday, November 27th at 11.00 CET.
by Anders Camitz · Published October 9, 2019
Nile launches new video off upcoming album "Vile Nilotic Rites"
Technical death metal Egyptologists Nile will release their ninth album, "Vile Nilotic Rites", on November 1st via Nuclear Blast. Now the band offers a lyric video for the second single and title track.
by Anders Camitz · Published September 10, 2019
Nile reveal details on new album "Vile Nilotic Rites"
Technical death metal Egyptologists Nile have announced they will release their ninth album, "Vile Nilotic Rites", on November 1st via Nuclear Blast. Now the band gives fans a taste of the album with the release of the first single "Long Shadows Of Dread".
Ok, got it...


New York, NY – July 30, 2018 – Camp Kuleshov, the annual trailer competition named for the Russian film theorist Lev Kuleshov, has issued its 2018 Call for Entries. This year, the competition is open to both post production as well as production companies, a result of the merger of AICP and AICE, the competition's original sponsoring organi-zation. It is additionally open to music companies who are members of the Association of Music Producers (AMP).
Camp Kuleshov consists of Editing, Graphic Design and Sound Design categories. In each competition, entrants are given a list of source films and genres to draw from and are presented with a brief tailored to each discipline. All post production assistants (ed-it, sound and graphics/visual effects) from AICP member companies are eligible, as are entries from entry-level employees, current assistant freelancers and interns.
In the Sound Design competition, the task is to create a new sound design for a 90-second excerpt from one of the source films that changes the film's context and/or in-tent and does not mimic the original film.
In the Graphic Design category, entrants are required to create an original opening title sequence for a film that conveys their impression or interpretation of the film. It should function as a device to prepare and position the audience for the film that fol-lows.
Anyone entering CK can choose any of the three categories in which to submit an entry, regardless of their own respective discipline or craft. In addition, the Chicago competi-tion will also include its 'Tent City' section, in which employees at AICP member com-panies can submit entries to any category even if they're not employed as assistants.
The Camp Kuleshov committee, which also includes Editor & Partner Brian Sepanik of The Colonie and Editor Val Lasser of Big Sky, is assembling a list of senior editors, art-ists and mixers to serve as 'Camp Coaches.' They'll be available during the time assis-tants are working on their entries to help guide them through their creative processes, offering advice and mentoring, but not solutions. In addition, any questions entrants may have regarding rules, eligibility or anything else can be directed to campk@aicp.com, and a 'Camp Counselor' will reply promptly.


A beautiful big hardcover book (350 pages), with superb concept drawings of the 3 classic movies, presented in various styles depending on the talented artist involved in drawing them.
I love some of the early concept drawings, where Lucas didn't have the full story yet, and we have Luke as a girl, Bespin cloud city as Alderaan, and 3 Star Destroyers following the Rebel Blockade Runner, and even one Imperial ship being destroyed in that battle etc.
A must have book for any SW fan.


What Are the Leading Car Brands That Make the Most Profit per Car Sold?
There was an automotive study conducted by the German economics professor Ferdinand Dudenhoffer that revealed information about car brands that make the most profit per car sold.
According to professor Ferdinand Dudenhoffer, Ferrari generated the most amount of money per car sold during the first half of 2018. The amount of profit generated per average Ferrari sold adds up to about $80,000.00, or approximately 69,000 euros.
According to the study, Porsche is making an average of $17,000 USD per car which adds up to twice as much as the next set of most profitable vehicle makes included in the study.
These three car makes generate approximately the same amount of profit per average car sold.
Maserati takes the sixth position with an average of €5,000 ($5,800) profit per car. Volvo made an average of slightly less profit than Maserati did.
Some car companies such as Rolls-Royce and Lamborghini have decided to keep their financial information private. Therefore, some car makes have not been included in this study.


Helped built several Startups in USA which got featured on TechCrunch and raised Series A and Series B funding after that. Always interested in helping out tech startup with advice.
19 How to get the hidden element value in capybara?
10 How can I delete all of my Git stashes at once?
8 Jest Snapshot testing vs unit testing?
8 Change type of varchar field to integer: "cannot be cast automatically to type integer"


text:
CGame* CreateGame()
{
	return GameServer()->Create<CIntroGame>("CIntroGame");
}

CResource<CLevel> CreateLevel()
{
	return CResource<CLevel>(new CLevel());
}

CHUDViewport* CreateHUD()
{
	CHUDViewport* pHUD = new CHUDViewport();
	return pHUD;
}

tstring GetInitialGameMode()
{
	return "intro";
}

pfnConditionsMet Game_GetInstructorConditions(const tstring& sConditions)
{
	return false;
}

REGISTER_ENTITY(CIntroGame);

NETVAR_TABLE_BEGIN(CIntroGame);
NETVAR_TABLE_END();

SAVEDATA_TABLE_BEGIN(CIntroGame);
SAVEDATA_TABLE_END();

INPUTS_TABLE_BEGIN(CIntroGame);
INPUTS_TABLE_END();

void CIntroGame::Precache()
{
	PrecacheParticleSystem("intro-explosion");
}

void CIntroGame::SetupGame(tstring sType)
{
	SetupIntro();
}

void SetupIntro(class CCommand* pCommand, tvector<tstring>& asTokens, const tstring& sCommand)
{
	for (size_t i = 0; i < GameServer()->GetMaxEntities(); i++)
	{
		CBaseEntity* pEntity = CBaseEntity::GetEntity(i);

		if (!pEntity)
			continue;

		if (pEntity == Game())
			continue;

		pEntity->Delete();
	}

	static_cast<CIntroGame*>(GameServer()->GetGame())->SetupIntro();
}

CCommand intro_setup("intro_setup", ::SetupIntro);

void CIntroGame::SetupIntro()
{
	Application()->SetMouseCursorEnabled(true);

	float flWidth = (float)CApplication::Get()->GetWindowWidth();
	float flHeight = (float)CApplication::Get()->GetWindowHeight();

	static_cast<CIntroWindow*>(Application())->GetGeneralWindow()->Reset();

	CScreen* pScreen = GameServer()->Create<CScreen>("CScreen");
	pScreen->SetName("screen");
	pScreen->SetScreenshot(static_cast<CIntroWindow*>(Application())->GetScreenshot());
	pScreen->SetGlobalOrigin(Vector(0, 0, 0));

	GameServer()->Create<CIntroCamera>("CIntroCamera");

	CTeam* pBugsTeam = GameServer()->Create<CTeam>("CTeam");
	pBugsTeam->SetColor(Color(255, 0, 0, 255));

	CBug* pBug;

	pBug = GameServer()->Create<CBug>("CBug");
	pBug->SetName("bug1");
	pBug->SetGlobalOrigin(Vector(-50, flWidth*0.16f, -20));
	pBug->SetGlobalAngles(EAngle(-10, -10, 0));
	pBug->FaceTurret(-40);
	pBugsTeam->AddEntity(pBug);

	pBug = GameServer()->Create<CBug>("CBug");
	pBug->SetName("bug2");
	pBug->SetGlobalOrigin(Vector(-50, flWidth*0.32f, 60));
	pBug->SetGlobalAngles(EAngle(-10, 20, 0));
	pBug->FaceTurret(40);
	pBugsTeam->AddEntity(pBug);

	pBug = GameServer()->Create<CBug>("CBug");
	pBug->SetName("bug3");
	pBug->SetGlobalOrigin(Vector(-50, flWidth*0.16f, flHeight*0.7f));
	pBug->SetGlobalAngles(EAngle(-10, -10, 0));
	pBug->FaceTurret(-40);
	pBugsTeam->AddEntity(pBug);

	pBug = GameServer()->Create<CBug>("CBug");
	pBug->SetName("bug4");
	pBug->SetGlobalOrigin(Vector(-50, flWidth*0.7f, 0));
	pBug->SetGlobalAngles(EAngle(-10, 20, 0));
	pBug->FaceTurret(40);
	pBugsTeam->AddEntity(pBug);

	pBug = GameServer()->Create<CBug>("CBug");
	pBug->SetName("bug5");
	pBug->SetGlobalOrigin(Vector(-50, flWidth*0.16f, -flHeight*0.7f));
	pBug->SetGlobalAngles(EAngle(-10, -10, 0));
	pBug->FaceTurret(-40);
	pBugsTeam->AddEntity(pBug);

	CIntroGeneral* pGeneral = GameServer()->Create<CIntroGeneral>("CIntroGeneral");
	pGeneral->SetName("general");

	CTeam* pDigitanksTeam = GameServer()->Create<CTeam>("CTeam");
	pDigitanksTeam->SetColor(Color(0, 64, 255, 255));

	CDigitank* pDigitank;

	pDigitank = GameServer()->Create<CDigitank>("CDigitank");
	pDigitank->SetName("digitank1");
	pDigitank->SetGlobalOrigin(Vector(-50, -flWidth*0.7f, -flHeight*0.7f));
	pDigitank->SetGlobalAngles(EAngle(-10, -70, 0));
	pDigitank->FaceTurret(0);
	pDigitanksTeam->AddEntity(pDigitank);

	pDigitank = GameServer()->Create<CDigitank>("CDigitank");
	pDigitank->SetName("digitank2");
	pDigitank->SetGlobalOrigin(Vector(-50, -flWidth*0.7f, 60));
	pDigitank->SetGlobalAngles(EAngle(-10, -70, 0));
	pDigitank->FaceTurret(0);
	pDigitanksTeam->AddEntity(pDigitank);

	pDigitank = GameServer()->Create<CDigitank>("CDigitank");
	pDigitank->SetName("digitank3");
	pDigitank->SetGlobalOrigin(Vector(-50, flWidth*0.7f, flHeight*0.7f));
	pDigitank->SetGlobalAngles(EAngle(-10, -70, 0));
	pDigitank->FaceTurret(0);
	pDigitanksTeam->AddEntity(pDigitank);

	ScriptManager()->ClearScripts();

	CScriptEvent* pEvent;

	CScript* pBustOutScript = ScriptManager()->AddScript("bustout");

	pEvent = pBustOutScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_PARTICLES;
	pEvent->m_flStartTime = 0;
	pEvent->m_sName = "intro-explosion";
	pEvent->m_vecOrigin = Vector(0, 0, 0);

	pEvent = pBustOutScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_PARTICLES;
	pEvent->m_flStartTime = 0.5;
	pEvent->m_sName = "intro-explosion-fragments";
	pEvent->m_vecOrigin = Vector(50, flWidth*0.25f, 20);

	pEvent = pBustOutScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_MOVEACTOR;
	pEvent->m_flStartTime = 0.5f;
	pEvent->m_flEndTime = 2.5f;
	pEvent->m_sName = "bug1";
	pEvent->m_vecOrigin = Vector(250, flWidth*0.35f, 60);
	pEvent->m_angAngles = EAngle(-10, 20, 0);

	pEvent = pBustOutScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_MOVEACTOR;
	pEvent->m_flStartTime = 1.5f;
	pEvent->m_flEndTime = 3.5f;
	pEvent->m_sName = "bug2";
	pEvent->m_vecOrigin = Vector(250, flWidth*0.14f, -20);
	pEvent->m_angAngles = EAngle(-10, 20, 0);

	pEvent = pBustOutScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_FIREOUTPUT;
	pEvent->m_flStartTime = 3.5;
	pEvent->m_sName = "bug1";
	pEvent->m_sOutput = "FireRandomly";

	pEvent = pBustOutScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_FIREOUTPUT;
	pEvent->m_flStartTime = 4.5f;
	pEvent->m_sName = "bug2";
	pEvent->m_sOutput = "FireRandomly";

	pEvent = pBustOutScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_FIREOUTPUT;
	pEvent->m_flStartTime = 8.5f;
	pEvent->m_sName = "general";
	pEvent->m_sOutput = "Deploy";

	CScript* pGeneralDebug1Script = ScriptManager()->AddScript("general-debug-1");

	pEvent = pGeneralDebug1Script->AddScriptEvent();
	pEvent->m_eEventClass = EC_PARTICLES;
	pEvent->m_flStartTime = 3;
	pEvent->m_sName = "intro-explosion";
	pEvent->m_vecOrigin = Vector(0, 0, 0);

	pEvent = pGeneralDebug1Script->AddScriptEvent();
	pEvent->m_eEventClass = EC_FIREOUTPUT;
	pEvent->m_flStartTime = 6;
	pEvent->m_sName = "general";
	pEvent->m_sOutput = "RetryDebugging";

	CScript* pGeneralDebug2Script = ScriptManager()->AddScript("general-debug-2");

	pEvent = pGeneralDebug2Script->AddScriptEvent();
	pEvent->m_eEventClass = EC_PARTICLES;
	pEvent->m_flStartTime = 3;
	pEvent->m_sName = "intro-explosion";
	pEvent->m_vecOrigin = Vector(0, 0, 0);

	pEvent = pGeneralDebug2Script->AddScriptEvent();
	pEvent->m_eEventClass = EC_MOVEACTOR;
	pEvent->m_flStartTime = 3.5f;
	pEvent->m_flEndTime = 5.5f;
	pEvent->m_sName = "bug3";
	pEvent->m_vecOrigin = Vector(250, flWidth*0.16f, flHeight*0.28f);
	pEvent->m_angAngles = EAngle(-10, 20, 0);

	pEvent = pGeneralDebug2Script->AddScriptEvent();
	pEvent->m_eEventClass = EC_MOVEACTOR;
	pEvent->m_flStartTime = 4.0f;
	pEvent->m_flEndTime = 6.0f;
	pEvent->m_sName = "bug4";
	pEvent->m_vecOrigin = Vector(250, flWidth*0.35f, -flHeight*0.1f);
	pEvent->m_angAngles = EAngle(-10, 20, 0);

	pEvent = pGeneralDebug2Script->AddScriptEvent();
	pEvent->m_eEventClass = EC_MOVEACTOR;
	pEvent->m_flStartTime = 4.5f;
	pEvent->m_flEndTime = 6.5f;
	pEvent->m_sName = "bug5";
	pEvent->m_vecOrigin = Vector(250, flWidth*0.16f, -flHeight*0.28f);
	pEvent->m_angAngles = EAngle(-10, 20, 0);

	pEvent = pGeneralDebug2Script->AddScriptEvent();
	pEvent->m_eEventClass = EC_FIREOUTPUT;
	pEvent->m_flStartTime = 4.0;
	pEvent->m_sName = "bug3";
	pEvent->m_sOutput = "FireRandomly";

	pEvent = pGeneralDebug2Script->AddScriptEvent();
	pEvent->m_eEventClass = EC_FIREOUTPUT;
	pEvent->m_flStartTime = 4.5f;
	pEvent->m_sName = "bug4";
	pEvent->m_sOutput = "FireRandomly";

	pEvent = pGeneralDebug2Script->AddScriptEvent();
	pEvent->m_eEventClass = EC_FIREOUTPUT;
	pEvent->m_flStartTime = 5.0f;
	pEvent->m_sName = "bug5";
	pEvent->m_sOutput = "FireRandomly";

	pEvent = pGeneralDebug2Script->AddScriptEvent();
	pEvent->m_eEventClass = EC_FIREOUTPUT;
	pEvent->m_flStartTime = 6;
	pEvent->m_sName = "general";
	pEvent->m_sOutput = "GiveUpDebugging";

	CScript* pDigitanksScript = ScriptManager()->AddScript("digitanks");

	pEvent = pDigitanksScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_MOVEACTOR;
	pEvent->m_flStartTime = 0.0f;
	pEvent->m_flEndTime = 1.0f;
	pEvent->m_sName = "digitank2";
	pEvent->m_vecOrigin = Vector(250, -flWidth*0.30f, flHeight*0.25f);
	pEvent->m_angAngles = EAngle(-20, -40, 0);

	pEvent = pDigitanksScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_MOVEACTOR;
	pEvent->m_flStartTime = 0.2f;
	pEvent->m_flEndTime = 1.2f;
	pEvent->m_sName = "digitank3";
	pEvent->m_vecOrigin = Vector(250, -flWidth*0.35f, flHeight*0.35f);
	pEvent->m_angAngles = EAngle(-20, -40, 0);

	pEvent = pDigitanksScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_MOVEACTOR;
	pEvent->m_flStartTime = 0.4f;
	pEvent->m_flEndTime = 1.4f;
	pEvent->m_sName = "digitank1";
	pEvent->m_vecOrigin = Vector(250, -flWidth*0.35f, flHeight*0.1f);
	pEvent->m_angAngles = EAngle(-20, -40, 0);

	pEvent = pDigitanksScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_FIREOUTPUT;
	pEvent->m_flStartTime = 2;
	pEvent->m_sName = "digitank1";
	pEvent->m_sOutput = "FireAt";
	pEvent->m_sArgs = "bug1";

	pEvent = pDigitanksScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_FIREOUTPUT;
	pEvent->m_flStartTime = 2.3f;
	pEvent->m_sName = "digitank2";
	pEvent->m_sOutput = "FireAt";
	pEvent->m_sArgs = "bug2";

	pEvent = pDigitanksScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_FIREOUTPUT;
	pEvent->m_flStartTime = 2.6f;
	pEvent->m_sName = "digitank3";
	pEvent->m_sOutput = "FireAt";
	pEvent->m_sArgs = "bug3";

	pEvent = pDigitanksScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_FIREOUTPUT;
	pEvent->m_flStartTime = 3;
	pEvent->m_sName = "digitank1";
	pEvent->m_sOutput = "FireAt";
	pEvent->m_sArgs = "bug4";

	pEvent = pDigitanksScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_FIREOUTPUT;
	pEvent->m_flStartTime = 3.3f;
	pEvent->m_sName = "digitank2";
	pEvent->m_sOutput = "FireAt";
	pEvent->m_sArgs = "bug5";

	pEvent = pDigitanksScript->AddScriptEvent();
	pEvent->m_eEventClass = EC_FIREOUTPUT;
	pEvent->m_flStartTime = 6;
	pEvent->m_sName = "general";
	pEvent->m_sOutput = "DigitanksWon";

	ScriptManager()->PlayScript("bustout");
}

void CIntroGame::Think()
{
	BaseClass::Think();

	ScriptManager()->Think();
}


text:
Home Latest News Minister Josephine Teo: We are giving Malaysian workers S$700 each for accommodation
Minister Josephine Teo: We are giving Malaysian workers S$700 each for accommodation
Malaysians entering Singapore
Using Singaporean taxpayers' money, Manpower Minister Josephine Wong announced that she is giving S$700 to each Malaysian worker for 14 nights' stay in Singapore:
"We are rolling out a plan to help with costs, to the tune of $50 per worker, per night for 14 nights."
About 415,000 Malaysians work in Singapore, and the PAP government is spending at least S$28 million to help these foreigners. This untimely spending came after calls for further financial assistance for Singaporeans went unanswered by the Lee Hsien Loong regime.
The government decision sparked anger among Singaporeans, who believe these foreigners should just go back to Malaysia for only 2 weeks. Singaporeans received only S$100 to S$300 each in the recent Budget assistance, a fraction of the S$900 the Malaysian received.
The Malaysia lockdown will end on 31 March.
Minister Josephine Teo said that the Singapore government even goes as far as helping the Malaysians to find accommodation:
"In the few hours that we've been working, we've been able to match more than 10,000 so far in the few short hours we had, so we're confident that those affected will be able to find suitable accommodation by the end of the night."
Previous articleMinister Lawrence Wong: Singapore might lock down
Next articleMalaysians complaining: Singapore bosses should pay for 14 days paid leave


Download this fact sheet from the VA Office of Health Equity on improving health care decision-making near the end of life.
The National Center for Ethics in Health Care serves as VA's authoritative resource for addressing the complex ethical issues that arise in patient care, health care management, and research.
We provide information, education, and consultation and oversee nationwide programs and quality improvement projects to help health care practitioners and administrators to understand and apply health care ethics standards.
We also provide information to Veterans, patients, and their families to help them understand ethical issues that relate to their health care experience.
Now available in TMS! Ethics and Professionalism Grand Rounds: Ethical Boundaries in the Patient-Provider Relationship - Providers will learn to define professional boundaries, explain their essential purpose in health care, and describe boundary crossings and violations. The training will illustrate special considerations pertaining to boundaries in mental health care and in small and rural communities. The speakers will also provide case examples of common boundary problems and propose potential solutions for health care professionals encountering these challenges.
New Podcast! "Mechanical Ventilation — An Option for Breathing Problems." The latest Dialed In podcast for Veterans looks at risks, benefits, and trade-offs of this life-sustaining treatment.
Now available in TMS! Ethics and Professionalism Grand Rounds: Ethical Challenges in Opioid Prescribing - Dr. Stephen Hunt and Dr. Lucile Burgo discuss several illustrative clinical cases involving opioid prescribing, analyze the ethically appropriate course of action, and provide a framework for health care providers to navigate the challenges of meeting patients' need for pain control while being mindful of the risks of opiates.
NCEHC retains the rights to the intellectual property and content contained on this website. This content is free to use. However, we kindly ask for attribution to VA National Center for Ethics In Health Care when it is used.