| @@ 374-649 (lines=276) @@ | ||
| 371 | ||
| 372 | angular.module('ui.bootstrap.carousel', []) |
|
| 373 | ||
| 374 | .controller('UibCarouselController', ['$scope', '$element', '$interval', '$timeout', '$animate', function($scope, $element, $interval, $timeout, $animate) { |
|
| 375 | var self = this, |
|
| 376 | slides = self.slides = $scope.slides = [], |
|
| 377 | SLIDE_DIRECTION = 'uib-slideDirection', |
|
| 378 | currentIndex = $scope.active, |
|
| 379 | currentInterval, isPlaying, bufferedTransitions = []; |
|
| 380 | ||
| 381 | var destroyed = false; |
|
| 382 | ||
| 383 | self.addSlide = function(slide, element) { |
|
| 384 | slides.push({ |
|
| 385 | slide: slide, |
|
| 386 | element: element |
|
| 387 | }); |
|
| 388 | slides.sort(function(a, b) { |
|
| 389 | return +a.slide.index - +b.slide.index; |
|
| 390 | }); |
|
| 391 | //if this is the first slide or the slide is set to active, select it |
|
| 392 | if (slide.index === $scope.active || slides.length === 1 && !angular.isNumber($scope.active)) { |
|
| 393 | if ($scope.$currentTransition) { |
|
| 394 | $scope.$currentTransition = null; |
|
| 395 | } |
|
| 396 | ||
| 397 | currentIndex = slide.index; |
|
| 398 | $scope.active = slide.index; |
|
| 399 | setActive(currentIndex); |
|
| 400 | self.select(slides[findSlideIndex(slide)]); |
|
| 401 | if (slides.length === 1) { |
|
| 402 | $scope.play(); |
|
| 403 | } |
|
| 404 | } |
|
| 405 | }; |
|
| 406 | ||
| 407 | self.getCurrentIndex = function() { |
|
| 408 | for (var i = 0; i < slides.length; i++) { |
|
| 409 | if (slides[i].slide.index === currentIndex) { |
|
| 410 | return i; |
|
| 411 | } |
|
| 412 | } |
|
| 413 | }; |
|
| 414 | ||
| 415 | self.next = $scope.next = function() { |
|
| 416 | var newIndex = (self.getCurrentIndex() + 1) % slides.length; |
|
| 417 | ||
| 418 | if (newIndex === 0 && $scope.noWrap()) { |
|
| 419 | $scope.pause(); |
|
| 420 | return; |
|
| 421 | } |
|
| 422 | ||
| 423 | return self.select(slides[newIndex], 'next'); |
|
| 424 | }; |
|
| 425 | ||
| 426 | self.prev = $scope.prev = function() { |
|
| 427 | var newIndex = self.getCurrentIndex() - 1 < 0 ? slides.length - 1 : self.getCurrentIndex() - 1; |
|
| 428 | ||
| 429 | if ($scope.noWrap() && newIndex === slides.length - 1) { |
|
| 430 | $scope.pause(); |
|
| 431 | return; |
|
| 432 | } |
|
| 433 | ||
| 434 | return self.select(slides[newIndex], 'prev'); |
|
| 435 | }; |
|
| 436 | ||
| 437 | self.removeSlide = function(slide) { |
|
| 438 | var index = findSlideIndex(slide); |
|
| 439 | ||
| 440 | var bufferedIndex = bufferedTransitions.indexOf(slides[index]); |
|
| 441 | if (bufferedIndex !== -1) { |
|
| 442 | bufferedTransitions.splice(bufferedIndex, 1); |
|
| 443 | } |
|
| 444 | ||
| 445 | //get the index of the slide inside the carousel |
|
| 446 | slides.splice(index, 1); |
|
| 447 | if (slides.length > 0 && currentIndex === index) { |
|
| 448 | if (index >= slides.length) { |
|
| 449 | currentIndex = slides.length - 1; |
|
| 450 | $scope.active = currentIndex; |
|
| 451 | setActive(currentIndex); |
|
| 452 | self.select(slides[slides.length - 1]); |
|
| 453 | } else { |
|
| 454 | currentIndex = index; |
|
| 455 | $scope.active = currentIndex; |
|
| 456 | setActive(currentIndex); |
|
| 457 | self.select(slides[index]); |
|
| 458 | } |
|
| 459 | } else if (currentIndex > index) { |
|
| 460 | currentIndex--; |
|
| 461 | $scope.active = currentIndex; |
|
| 462 | } |
|
| 463 | ||
| 464 | //clean the active value when no more slide |
|
| 465 | if (slides.length === 0) { |
|
| 466 | currentIndex = null; |
|
| 467 | $scope.active = null; |
|
| 468 | clearBufferedTransitions(); |
|
| 469 | } |
|
| 470 | }; |
|
| 471 | ||
| 472 | /* direction: "prev" or "next" */ |
|
| 473 | self.select = $scope.select = function(nextSlide, direction) { |
|
| 474 | var nextIndex = findSlideIndex(nextSlide.slide); |
|
| 475 | //Decide direction if it's not given |
|
| 476 | if (direction === undefined) { |
|
| 477 | direction = nextIndex > self.getCurrentIndex() ? 'next' : 'prev'; |
|
| 478 | } |
|
| 479 | //Prevent this user-triggered transition from occurring if there is already one in progress |
|
| 480 | if (nextSlide.slide.index !== currentIndex && |
|
| 481 | !$scope.$currentTransition) { |
|
| 482 | goNext(nextSlide.slide, nextIndex, direction); |
|
| 483 | } else if (nextSlide && nextSlide.slide.index !== currentIndex && $scope.$currentTransition) { |
|
| 484 | bufferedTransitions.push(slides[nextIndex]); |
|
| 485 | } |
|
| 486 | }; |
|
| 487 | ||
| 488 | /* Allow outside people to call indexOf on slides array */ |
|
| 489 | $scope.indexOfSlide = function(slide) { |
|
| 490 | return +slide.slide.index; |
|
| 491 | }; |
|
| 492 | ||
| 493 | $scope.isActive = function(slide) { |
|
| 494 | return $scope.active === slide.slide.index; |
|
| 495 | }; |
|
| 496 | ||
| 497 | $scope.isPrevDisabled = function() { |
|
| 498 | return $scope.active === 0 && $scope.noWrap(); |
|
| 499 | }; |
|
| 500 | ||
| 501 | $scope.isNextDisabled = function() { |
|
| 502 | return $scope.active === slides.length - 1 && $scope.noWrap(); |
|
| 503 | }; |
|
| 504 | ||
| 505 | $scope.pause = function() { |
|
| 506 | if (!$scope.noPause) { |
|
| 507 | isPlaying = false; |
|
| 508 | resetTimer(); |
|
| 509 | } |
|
| 510 | }; |
|
| 511 | ||
| 512 | $scope.play = function() { |
|
| 513 | if (!isPlaying) { |
|
| 514 | isPlaying = true; |
|
| 515 | restartTimer(); |
|
| 516 | } |
|
| 517 | }; |
|
| 518 | ||
| 519 | $scope.$on('$destroy', function() { |
|
| 520 | destroyed = true; |
|
| 521 | resetTimer(); |
|
| 522 | }); |
|
| 523 | ||
| 524 | $scope.$watch('noTransition', function(noTransition) { |
|
| 525 | $animate.enabled($element, !noTransition); |
|
| 526 | }); |
|
| 527 | ||
| 528 | $scope.$watch('interval', restartTimer); |
|
| 529 | ||
| 530 | $scope.$watchCollection('slides', resetTransition); |
|
| 531 | ||
| 532 | $scope.$watch('active', function(index) { |
|
| 533 | if (angular.isNumber(index) && currentIndex !== index) { |
|
| 534 | for (var i = 0; i < slides.length; i++) { |
|
| 535 | if (slides[i].slide.index === index) { |
|
| 536 | index = i; |
|
| 537 | break; |
|
| 538 | } |
|
| 539 | } |
|
| 540 | ||
| 541 | var slide = slides[index]; |
|
| 542 | if (slide) { |
|
| 543 | setActive(index); |
|
| 544 | self.select(slides[index]); |
|
| 545 | currentIndex = index; |
|
| 546 | } |
|
| 547 | } |
|
| 548 | }); |
|
| 549 | ||
| 550 | function clearBufferedTransitions() { |
|
| 551 | while (bufferedTransitions.length) { |
|
| 552 | bufferedTransitions.shift(); |
|
| 553 | } |
|
| 554 | } |
|
| 555 | ||
| 556 | function getSlideByIndex(index) { |
|
| 557 | for (var i = 0, l = slides.length; i < l; ++i) { |
|
| 558 | if (slides[i].index === index) { |
|
| 559 | return slides[i]; |
|
| 560 | } |
|
| 561 | } |
|
| 562 | } |
|
| 563 | ||
| 564 | function setActive(index) { |
|
| 565 | for (var i = 0; i < slides.length; i++) { |
|
| 566 | slides[i].slide.active = i === index; |
|
| 567 | } |
|
| 568 | } |
|
| 569 | ||
| 570 | function goNext(slide, index, direction) { |
|
| 571 | if (destroyed) { |
|
| 572 | return; |
|
| 573 | } |
|
| 574 | ||
| 575 | angular.extend(slide, {direction: direction}); |
|
| 576 | angular.extend(slides[currentIndex].slide || {}, {direction: direction}); |
|
| 577 | if ($animate.enabled($element) && !$scope.$currentTransition && |
|
| 578 | slides[index].element && self.slides.length > 1) { |
|
| 579 | slides[index].element.data(SLIDE_DIRECTION, slide.direction); |
|
| 580 | var currentIdx = self.getCurrentIndex(); |
|
| 581 | ||
| 582 | if (angular.isNumber(currentIdx) && slides[currentIdx].element) { |
|
| 583 | slides[currentIdx].element.data(SLIDE_DIRECTION, slide.direction); |
|
| 584 | } |
|
| 585 | ||
| 586 | $scope.$currentTransition = true; |
|
| 587 | $animate.on('addClass', slides[index].element, function(element, phase) { |
|
| 588 | if (phase === 'close') { |
|
| 589 | $scope.$currentTransition = null; |
|
| 590 | $animate.off('addClass', element); |
|
| 591 | if (bufferedTransitions.length) { |
|
| 592 | var nextSlide = bufferedTransitions.pop().slide; |
|
| 593 | var nextIndex = nextSlide.index; |
|
| 594 | var nextDirection = nextIndex > self.getCurrentIndex() ? 'next' : 'prev'; |
|
| 595 | clearBufferedTransitions(); |
|
| 596 | ||
| 597 | goNext(nextSlide, nextIndex, nextDirection); |
|
| 598 | } |
|
| 599 | } |
|
| 600 | }); |
|
| 601 | } |
|
| 602 | ||
| 603 | $scope.active = slide.index; |
|
| 604 | currentIndex = slide.index; |
|
| 605 | setActive(index); |
|
| 606 | ||
| 607 | //every time you change slides, reset the timer |
|
| 608 | restartTimer(); |
|
| 609 | } |
|
| 610 | ||
| 611 | function findSlideIndex(slide) { |
|
| 612 | for (var i = 0; i < slides.length; i++) { |
|
| 613 | if (slides[i].slide === slide) { |
|
| 614 | return i; |
|
| 615 | } |
|
| 616 | } |
|
| 617 | } |
|
| 618 | ||
| 619 | function resetTimer() { |
|
| 620 | if (currentInterval) { |
|
| 621 | $interval.cancel(currentInterval); |
|
| 622 | currentInterval = null; |
|
| 623 | } |
|
| 624 | } |
|
| 625 | ||
| 626 | function resetTransition(slides) { |
|
| 627 | if (!slides.length) { |
|
| 628 | $scope.$currentTransition = null; |
|
| 629 | clearBufferedTransitions(); |
|
| 630 | } |
|
| 631 | } |
|
| 632 | ||
| 633 | function restartTimer() { |
|
| 634 | resetTimer(); |
|
| 635 | var interval = +$scope.interval; |
|
| 636 | if (!isNaN(interval) && interval > 0) { |
|
| 637 | currentInterval = $interval(timerFn, interval); |
|
| 638 | } |
|
| 639 | } |
|
| 640 | ||
| 641 | function timerFn() { |
|
| 642 | var interval = +$scope.interval; |
|
| 643 | if (isPlaying && !isNaN(interval) && interval > 0 && slides.length) { |
|
| 644 | $scope.next(); |
|
| 645 | } else { |
|
| 646 | $scope.pause(); |
|
| 647 | } |
|
| 648 | } |
|
| 649 | }]) |
|
| 650 | ||
| 651 | .directive('uibCarousel', function() { |
|
| 652 | return { |
|
| @@ 373-648 (lines=276) @@ | ||
| 370 | ||
| 371 | angular.module('ui.bootstrap.carousel', []) |
|
| 372 | ||
| 373 | .controller('UibCarouselController', ['$scope', '$element', '$interval', '$timeout', '$animate', function($scope, $element, $interval, $timeout, $animate) { |
|
| 374 | var self = this, |
|
| 375 | slides = self.slides = $scope.slides = [], |
|
| 376 | SLIDE_DIRECTION = 'uib-slideDirection', |
|
| 377 | currentIndex = $scope.active, |
|
| 378 | currentInterval, isPlaying, bufferedTransitions = []; |
|
| 379 | ||
| 380 | var destroyed = false; |
|
| 381 | ||
| 382 | self.addSlide = function(slide, element) { |
|
| 383 | slides.push({ |
|
| 384 | slide: slide, |
|
| 385 | element: element |
|
| 386 | }); |
|
| 387 | slides.sort(function(a, b) { |
|
| 388 | return +a.slide.index - +b.slide.index; |
|
| 389 | }); |
|
| 390 | //if this is the first slide or the slide is set to active, select it |
|
| 391 | if (slide.index === $scope.active || slides.length === 1 && !angular.isNumber($scope.active)) { |
|
| 392 | if ($scope.$currentTransition) { |
|
| 393 | $scope.$currentTransition = null; |
|
| 394 | } |
|
| 395 | ||
| 396 | currentIndex = slide.index; |
|
| 397 | $scope.active = slide.index; |
|
| 398 | setActive(currentIndex); |
|
| 399 | self.select(slides[findSlideIndex(slide)]); |
|
| 400 | if (slides.length === 1) { |
|
| 401 | $scope.play(); |
|
| 402 | } |
|
| 403 | } |
|
| 404 | }; |
|
| 405 | ||
| 406 | self.getCurrentIndex = function() { |
|
| 407 | for (var i = 0; i < slides.length; i++) { |
|
| 408 | if (slides[i].slide.index === currentIndex) { |
|
| 409 | return i; |
|
| 410 | } |
|
| 411 | } |
|
| 412 | }; |
|
| 413 | ||
| 414 | self.next = $scope.next = function() { |
|
| 415 | var newIndex = (self.getCurrentIndex() + 1) % slides.length; |
|
| 416 | ||
| 417 | if (newIndex === 0 && $scope.noWrap()) { |
|
| 418 | $scope.pause(); |
|
| 419 | return; |
|
| 420 | } |
|
| 421 | ||
| 422 | return self.select(slides[newIndex], 'next'); |
|
| 423 | }; |
|
| 424 | ||
| 425 | self.prev = $scope.prev = function() { |
|
| 426 | var newIndex = self.getCurrentIndex() - 1 < 0 ? slides.length - 1 : self.getCurrentIndex() - 1; |
|
| 427 | ||
| 428 | if ($scope.noWrap() && newIndex === slides.length - 1) { |
|
| 429 | $scope.pause(); |
|
| 430 | return; |
|
| 431 | } |
|
| 432 | ||
| 433 | return self.select(slides[newIndex], 'prev'); |
|
| 434 | }; |
|
| 435 | ||
| 436 | self.removeSlide = function(slide) { |
|
| 437 | var index = findSlideIndex(slide); |
|
| 438 | ||
| 439 | var bufferedIndex = bufferedTransitions.indexOf(slides[index]); |
|
| 440 | if (bufferedIndex !== -1) { |
|
| 441 | bufferedTransitions.splice(bufferedIndex, 1); |
|
| 442 | } |
|
| 443 | ||
| 444 | //get the index of the slide inside the carousel |
|
| 445 | slides.splice(index, 1); |
|
| 446 | if (slides.length > 0 && currentIndex === index) { |
|
| 447 | if (index >= slides.length) { |
|
| 448 | currentIndex = slides.length - 1; |
|
| 449 | $scope.active = currentIndex; |
|
| 450 | setActive(currentIndex); |
|
| 451 | self.select(slides[slides.length - 1]); |
|
| 452 | } else { |
|
| 453 | currentIndex = index; |
|
| 454 | $scope.active = currentIndex; |
|
| 455 | setActive(currentIndex); |
|
| 456 | self.select(slides[index]); |
|
| 457 | } |
|
| 458 | } else if (currentIndex > index) { |
|
| 459 | currentIndex--; |
|
| 460 | $scope.active = currentIndex; |
|
| 461 | } |
|
| 462 | ||
| 463 | //clean the active value when no more slide |
|
| 464 | if (slides.length === 0) { |
|
| 465 | currentIndex = null; |
|
| 466 | $scope.active = null; |
|
| 467 | clearBufferedTransitions(); |
|
| 468 | } |
|
| 469 | }; |
|
| 470 | ||
| 471 | /* direction: "prev" or "next" */ |
|
| 472 | self.select = $scope.select = function(nextSlide, direction) { |
|
| 473 | var nextIndex = findSlideIndex(nextSlide.slide); |
|
| 474 | //Decide direction if it's not given |
|
| 475 | if (direction === undefined) { |
|
| 476 | direction = nextIndex > self.getCurrentIndex() ? 'next' : 'prev'; |
|
| 477 | } |
|
| 478 | //Prevent this user-triggered transition from occurring if there is already one in progress |
|
| 479 | if (nextSlide.slide.index !== currentIndex && |
|
| 480 | !$scope.$currentTransition) { |
|
| 481 | goNext(nextSlide.slide, nextIndex, direction); |
|
| 482 | } else if (nextSlide && nextSlide.slide.index !== currentIndex && $scope.$currentTransition) { |
|
| 483 | bufferedTransitions.push(slides[nextIndex]); |
|
| 484 | } |
|
| 485 | }; |
|
| 486 | ||
| 487 | /* Allow outside people to call indexOf on slides array */ |
|
| 488 | $scope.indexOfSlide = function(slide) { |
|
| 489 | return +slide.slide.index; |
|
| 490 | }; |
|
| 491 | ||
| 492 | $scope.isActive = function(slide) { |
|
| 493 | return $scope.active === slide.slide.index; |
|
| 494 | }; |
|
| 495 | ||
| 496 | $scope.isPrevDisabled = function() { |
|
| 497 | return $scope.active === 0 && $scope.noWrap(); |
|
| 498 | }; |
|
| 499 | ||
| 500 | $scope.isNextDisabled = function() { |
|
| 501 | return $scope.active === slides.length - 1 && $scope.noWrap(); |
|
| 502 | }; |
|
| 503 | ||
| 504 | $scope.pause = function() { |
|
| 505 | if (!$scope.noPause) { |
|
| 506 | isPlaying = false; |
|
| 507 | resetTimer(); |
|
| 508 | } |
|
| 509 | }; |
|
| 510 | ||
| 511 | $scope.play = function() { |
|
| 512 | if (!isPlaying) { |
|
| 513 | isPlaying = true; |
|
| 514 | restartTimer(); |
|
| 515 | } |
|
| 516 | }; |
|
| 517 | ||
| 518 | $scope.$on('$destroy', function() { |
|
| 519 | destroyed = true; |
|
| 520 | resetTimer(); |
|
| 521 | }); |
|
| 522 | ||
| 523 | $scope.$watch('noTransition', function(noTransition) { |
|
| 524 | $animate.enabled($element, !noTransition); |
|
| 525 | }); |
|
| 526 | ||
| 527 | $scope.$watch('interval', restartTimer); |
|
| 528 | ||
| 529 | $scope.$watchCollection('slides', resetTransition); |
|
| 530 | ||
| 531 | $scope.$watch('active', function(index) { |
|
| 532 | if (angular.isNumber(index) && currentIndex !== index) { |
|
| 533 | for (var i = 0; i < slides.length; i++) { |
|
| 534 | if (slides[i].slide.index === index) { |
|
| 535 | index = i; |
|
| 536 | break; |
|
| 537 | } |
|
| 538 | } |
|
| 539 | ||
| 540 | var slide = slides[index]; |
|
| 541 | if (slide) { |
|
| 542 | setActive(index); |
|
| 543 | self.select(slides[index]); |
|
| 544 | currentIndex = index; |
|
| 545 | } |
|
| 546 | } |
|
| 547 | }); |
|
| 548 | ||
| 549 | function clearBufferedTransitions() { |
|
| 550 | while (bufferedTransitions.length) { |
|
| 551 | bufferedTransitions.shift(); |
|
| 552 | } |
|
| 553 | } |
|
| 554 | ||
| 555 | function getSlideByIndex(index) { |
|
| 556 | for (var i = 0, l = slides.length; i < l; ++i) { |
|
| 557 | if (slides[i].index === index) { |
|
| 558 | return slides[i]; |
|
| 559 | } |
|
| 560 | } |
|
| 561 | } |
|
| 562 | ||
| 563 | function setActive(index) { |
|
| 564 | for (var i = 0; i < slides.length; i++) { |
|
| 565 | slides[i].slide.active = i === index; |
|
| 566 | } |
|
| 567 | } |
|
| 568 | ||
| 569 | function goNext(slide, index, direction) { |
|
| 570 | if (destroyed) { |
|
| 571 | return; |
|
| 572 | } |
|
| 573 | ||
| 574 | angular.extend(slide, {direction: direction}); |
|
| 575 | angular.extend(slides[currentIndex].slide || {}, {direction: direction}); |
|
| 576 | if ($animate.enabled($element) && !$scope.$currentTransition && |
|
| 577 | slides[index].element && self.slides.length > 1) { |
|
| 578 | slides[index].element.data(SLIDE_DIRECTION, slide.direction); |
|
| 579 | var currentIdx = self.getCurrentIndex(); |
|
| 580 | ||
| 581 | if (angular.isNumber(currentIdx) && slides[currentIdx].element) { |
|
| 582 | slides[currentIdx].element.data(SLIDE_DIRECTION, slide.direction); |
|
| 583 | } |
|
| 584 | ||
| 585 | $scope.$currentTransition = true; |
|
| 586 | $animate.on('addClass', slides[index].element, function(element, phase) { |
|
| 587 | if (phase === 'close') { |
|
| 588 | $scope.$currentTransition = null; |
|
| 589 | $animate.off('addClass', element); |
|
| 590 | if (bufferedTransitions.length) { |
|
| 591 | var nextSlide = bufferedTransitions.pop().slide; |
|
| 592 | var nextIndex = nextSlide.index; |
|
| 593 | var nextDirection = nextIndex > self.getCurrentIndex() ? 'next' : 'prev'; |
|
| 594 | clearBufferedTransitions(); |
|
| 595 | ||
| 596 | goNext(nextSlide, nextIndex, nextDirection); |
|
| 597 | } |
|
| 598 | } |
|
| 599 | }); |
|
| 600 | } |
|
| 601 | ||
| 602 | $scope.active = slide.index; |
|
| 603 | currentIndex = slide.index; |
|
| 604 | setActive(index); |
|
| 605 | ||
| 606 | //every time you change slides, reset the timer |
|
| 607 | restartTimer(); |
|
| 608 | } |
|
| 609 | ||
| 610 | function findSlideIndex(slide) { |
|
| 611 | for (var i = 0; i < slides.length; i++) { |
|
| 612 | if (slides[i].slide === slide) { |
|
| 613 | return i; |
|
| 614 | } |
|
| 615 | } |
|
| 616 | } |
|
| 617 | ||
| 618 | function resetTimer() { |
|
| 619 | if (currentInterval) { |
|
| 620 | $interval.cancel(currentInterval); |
|
| 621 | currentInterval = null; |
|
| 622 | } |
|
| 623 | } |
|
| 624 | ||
| 625 | function resetTransition(slides) { |
|
| 626 | if (!slides.length) { |
|
| 627 | $scope.$currentTransition = null; |
|
| 628 | clearBufferedTransitions(); |
|
| 629 | } |
|
| 630 | } |
|
| 631 | ||
| 632 | function restartTimer() { |
|
| 633 | resetTimer(); |
|
| 634 | var interval = +$scope.interval; |
|
| 635 | if (!isNaN(interval) && interval > 0) { |
|
| 636 | currentInterval = $interval(timerFn, interval); |
|
| 637 | } |
|
| 638 | } |
|
| 639 | ||
| 640 | function timerFn() { |
|
| 641 | var interval = +$scope.interval; |
|
| 642 | if (isPlaying && !isNaN(interval) && interval > 0 && slides.length) { |
|
| 643 | $scope.next(); |
|
| 644 | } else { |
|
| 645 | $scope.pause(); |
|
| 646 | } |
|
| 647 | } |
|
| 648 | }]) |
|
| 649 | ||
| 650 | .directive('uibCarousel', function() { |
|
| 651 | return { |
|