<commit_before>(function() {
'use strict';
/**
 * @ngdoc module
 * @name material.components.select
 */

/***************************************************

### TODO ###
**DOCUMENTATION AND DEMOS**

- [ ] ng-model with child mdOptions (basic)
- [ ] ng-model="foo" ng-model-options="{ trackBy: '$value.id' }" for objects
- [ ] mdOption with value
- [ ] Usage with input inside
- [ ] Usage with md-multiple

### TODO - POST RC1 ###
- [ ] Abstract placement logic in $mdSelect service to $mdMenu service

***************************************************/

var SELECT_EDGE_MARGIN = 8;
var selectNextId = 0;

angular.module('material.components.select', [
  'material.core',
  'material.components.backdrop'
])
.directive('mdSelect', SelectDirective)
.directive('mdSelectMenu', SelectMenuDirective)
.directive('mdOption', OptionDirective)
.directive('mdOptgroup', OptgroupDirective)
.provider('$mdSelect', SelectProvider);


/**
 * @ngdoc directive
 * @name mdSelect
 * @restrict E
 * @module material.components.select
 *
 * @description Displays a select box, bound to an ng-model.
 *
 * @param {expression} ng-model The model!
 * @param {boolean=} multiple Whether it's multiple.
 * @param {string=} placeholder Placeholder hint text.
 *
 * @usage
 * With a placeholder (label is added dynamically)
 * <hljs lang="html">
 *   <md-select
 *     ng-model="someModel"
 *     placeholder="Select a state">
 *     <md-option ng-value="opt" ng-repeat="opt in neighborhoods2">{{ opt }}</md-option>
 *   </md-select>
 * </hljs>
 *
 * With an explicit label
 * <hljs lang="html">
 *   <md-select
 *     ng-model="someModel">
 *     <md-select-label>Select a state</md-select-label>
 *     <md-option ng-value="opt" ng-repeat="opt in neighborhoods2">{{ opt }}</md-option>
 *   </md-select>
 * </hljs>
 */
function SelectDirective($mdSelect, $mdUtil, $mdTheming, $interpolate, $compile, $parse) {
  var intStart = $interpolate.startSymbol();
  var intEnd = $interpolate.endSymbol();

  return {
    restrict: 'E',
    require: '?ngModel',
    compile: compile
  };

  function compile(element, attr) {
    // The user is allowed to provide a label for the select as md-select-label child
    var labelEl = element.find('md-select-label').remove();

    // If not provided, we automatically make one
    if (!labelEl.length) {
      labelEl = angular.element('<md-select-label><span></span></md-select-label>');
    }
    labelEl.append('<span class="md-select-icon" aria-hidden="true"></span>');
    labelEl.addClass('md-select-label');
    labelEl.addClass(intStart + attr.ngModel + ' !== undefined ? \'\' : \'md-placeholder\'' + intEnd);
    labelEl.attr('id', 'select_label_' + $mdUtil.nextUid());

    // There's got to be an md-content inside. If there's not one, let's add it.
    if (!element.find('md-content').length) {
      element.append( angular.element('<md-content>').append(element.contents()) );
    }

    // Add progress spinner for md-options-loading
    if (attr.mdOnOpen) {
      element.find('md-content').prepend(
        angular.element('<md-progress-circular>')
               .attr('md-mode', 'indeterminate')
               .attr('ng-hide', '$$loadingAsyncDone')
               .wrap('<div>')
               .parent()
      );
    }

    // Use everything that's left inside element.contents() as the contents of the menu
    var selectTemplate = angular.element(
      '<div class="md-select-menu-container">' +
        '<md-select-menu ' +
        (angular.isDefined(attr.multiple) ? 'multiple' : '') + '>' +
          element.html() +
        '</md-select-menu></div>');

    element.empty().append(labelEl);

    $mdTheming(element);

    return function postLink(scope, element, attr, ngModel) {
      var isOpen;
      var labelEl = element.find('md-select-label');
      var customLabel = labelEl.text().length !== 0;
      if (!customLabel) labelEl = labelEl.children().eq(0);
      setInitialLabelValue();

      attr.$observe('disabled', function(disabled) {
        if (disabled !== undefined) {
          element.attr('tabindex', -1);
          element.off('click', openSelect);
          element.off('keydown', openOnKeypress);
        } else {
          element.attr('tabindex', 0);
          element.on('click', openSelect);
          element.on('keydown', openOnKeypress);
        }
      });

      if (attr.disabled === undefined) {
        element.on('click', openSelect);
        element.on('keydown', openOnKeypress);
      }

      element.attr({
        'role': 'combobox',
        'id': 'select_' + $mdUtil.nextUid(),
        'aria-haspopup': true,
        'aria-expanded': 'false',
        'aria-labelledby': labelEl.attr('id')
      });

      scope.$on('$destroy', function() {
        if (isOpen) {
          $mdSelect.cancel();
        }
      });

      // Create a fake select to find out the label value
      function setInitialLabelValue() {
        if ($parse(attr.ngModel)(scope)) {
          var fakeSelectEl = angular.element(selectTemplate).find('md-select-menu');
          fakeSelectEl.data('$ngModelController', ngModel);
          var fakeSelectScope = scope.$new();
          fakeSelectEl = $compile(fakeSelectEl)(fakeSelectScope);
          var fakeSelectCtrl = fakeSelectEl.controller('mdSelectMenu');
          fakeSelectScope.$$postDigest(function() {
            ngModel.$render();
            setLabelText(fakeSelectCtrl.selectedLabels());
            fakeSelectEl.scope().$destroy();
          });
        } else {
          setLabelText();
        }
      }<commit_msg>fix(select): fix duplicate options when using ng-repeat<commit_after>(function() {
'use strict';
/**
 * @ngdoc module
 * @name material.components.select
 */

/***************************************************

### TODO ###
**DOCUMENTATION AND DEMOS**

- [ ] ng-model with child mdOptions (basic)
- [ ] ng-model="foo" ng-model-options="{ trackBy: '$value.id' }" for objects
- [ ] mdOption with value
- [ ] Usage with input inside
- [ ] Usage with md-multiple

### TODO - POST RC1 ###
- [ ] Abstract placement logic in $mdSelect service to $mdMenu service

***************************************************/

var SELECT_EDGE_MARGIN = 8;
var selectNextId = 0;

angular.module('material.components.select', [
  'material.core',
  'material.components.backdrop'
])
.directive('mdSelect', SelectDirective)
.directive('mdSelectMenu', SelectMenuDirective)
.directive('mdOption', OptionDirective)
.directive('mdOptgroup', OptgroupDirective)
.provider('$mdSelect', SelectProvider);


/**
 * @ngdoc directive
 * @name mdSelect
 * @restrict E
 * @module material.components.select
 *
 * @description Displays a select box, bound to an ng-model.
 *
 * @param {expression} ng-model The model!
 * @param {boolean=} multiple Whether it's multiple.
 * @param {string=} placeholder Placeholder hint text.
 *
 * @usage
 * With a placeholder (label is added dynamically)
 * <hljs lang="html">
 *   <md-select
 *     ng-model="someModel"
 *     placeholder="Select a state">
 *     <md-option ng-value="opt" ng-repeat="opt in neighborhoods2">{{ opt }}</md-option>
 *   </md-select>
 * </hljs>
 *
 * With an explicit label
 * <hljs lang="html">
 *   <md-select
 *     ng-model="someModel">
 *     <md-select-label>Select a state</md-select-label>
 *     <md-option ng-value="opt" ng-repeat="opt in neighborhoods2">{{ opt }}</md-option>
 *   </md-select>
 * </hljs>
 */
function SelectDirective($mdSelect, $mdUtil, $mdTheming, $interpolate, $compile, $parse) {
  var intStart = $interpolate.startSymbol();
  var intEnd = $interpolate.endSymbol();

  return {
    restrict: 'E',
    require: '?ngModel',
    compile: compile
  };

  function compile(element, attr) {
    // The user is allowed to provide a label for the select as md-select-label child
    var labelEl = element.find('md-select-label').remove();

    // If not provided, we automatically make one
    if (!labelEl.length) {
      labelEl = angular.element('<md-select-label><span></span></md-select-label>');
    }
    labelEl.append('<span class="md-select-icon" aria-hidden="true"></span>');
    labelEl.addClass('md-select-label');
    labelEl.addClass(intStart + attr.ngModel + ' !== undefined ? \'\' : \'md-placeholder\'' + intEnd);
    labelEl.attr('id', 'select_label_' + $mdUtil.nextUid());

    // There's got to be an md-content inside. If there's not one, let's add it.
    if (!element.find('md-content').length) {
      element.append( angular.element('<md-content>').append(element.contents()) );
    }

    // Add progress spinner for md-options-loading
    if (attr.mdOnOpen) {
      element.find('md-content').prepend(
        angular.element('<md-progress-circular>')
               .attr('md-mode', 'indeterminate')
               .attr('ng-hide', '$$loadingAsyncDone')
               .wrap('<div>')
               .parent()
      );
    }

    // Use everything that's left inside element.contents() as the contents of the menu
    var selectTemplate = angular.element(
      '<div class="md-select-menu-container">' +
        '<md-select-menu ' +
        (angular.isDefined(attr.multiple) ? 'multiple' : '') + '>' +
          element.html() +
        '</md-select-menu></div>');

    element.empty().append(labelEl);

    $mdTheming(element);

    return function postLink(scope, element, attr, ngModel) {
      var isOpen;
      var labelEl = element.find('md-select-label');
      var customLabel = labelEl.text().length !== 0;
      if (!customLabel) labelEl = labelEl.children().eq(0);
      setInitialLabelValue();

      attr.$observe('disabled', function(disabled) {
        if (disabled !== undefined) {
          element.attr('tabindex', -1);
          element.off('click', openSelect);
          element.off('keydown', openOnKeypress);
        } else {
          element.attr('tabindex', 0);
          element.on('click', openSelect);
          element.on('keydown', openOnKeypress);
        }
      });

      if (attr.disabled === undefined) {
        element.on('click', openSelect);
        element.on('keydown', openOnKeypress);
      }

      element.attr({
        'role': 'combobox',
        'id': 'select_' + $mdUtil.nextUid(),
        'aria-haspopup': true,
        'aria-expanded': 'false',
        'aria-labelledby': labelEl.attr('id')
      });

      scope.$on('$destroy', function() {
        if (isOpen) {
          $mdSelect.cancel();
        }
      });

      // Create a fake select to find out the label value
      function setInitialLabelValue() {
        if ($parse(attr.ngModel)(scope)) {
          var fakeSelectEl = angular.element(selectTemplate.clone()).find('md-select-menu');
          fakeSelectEl.data('$ngModelController', ngModel);
          var fakeSelectScope = scope.$new();
          fakeSelectEl = $compile(fakeSelectEl)(fakeSelectScope);
          var fakeSelectCtrl = fakeSelectEl.controller('mdSelectMenu');
          fakeSelectScope.$$postDigest(function() {
            ngModel.$render();
            setLabelText(fakeSelectCtrl.selectedLabels());
            fakeSelectEl.scope().$destroy();
          });
        } else {
          setLabelText();
        }
      }
{'fraction_non_alphanumeric': 0.17849443047071506, 'fraction_numerical': 0.0016169601149838304, 'mean_word_length': 2.9242157208318647, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3287414', 'n_tokens_mistral': 3372, 'n_tokens_neox': 3288, 'n_words': 718}