ember_debug/object-inspector.js
function customizeProperties(mixinDetails, propertyInfo) {
  let newMixinDetails = [];
  let neededProperties = {};
  let groups = propertyInfo.groups || [];
  let skipProperties = propertyInfo.skipProperties || [];
  let skipMixins = propertyInfo.skipMixins || [];

  if (groups.length) {
    mixinDetails[0].expand = false;
  }

  groups.forEach(group => {
    group.properties.forEach(prop => {
      neededProperties[prop] = true;
    });
  });

  mixinDetails.forEach(mixin => {
    let newProperties = [];
    mixin.properties.forEach(item => {
      // If 2.10.0 or 2.10.x but < 2.11
      if (compareVersion(VERSION, '2.10.0') === 0 ||
        (compareVersion(VERSION, '2.10.0') === 1 && compareVersion(VERSION, '2.11.0') === -1)) {
        skipProperties = twoTenfilterHack(item.name, skipProperties);
      }
      if (skipProperties.indexOf(item.name) !== -1) {
        return true;
      }

      if (!item.overridden && neededProperties.hasOwnProperty(item.name) && neededProperties[item.name]) {
        neededProperties[item.name] = item;
      } else {
        newProperties.push(item);
      }
    });
    mixin.properties = newProperties;
    if (skipMixins.indexOf(mixin.name) === -1) {
      newMixinDetails.push(mixin);
    }
  });

  groups.slice().reverse().forEach(group => {
    let newMixin = { name: group.name, expand: group.expand, properties: [] };
    group.properties.forEach(function(prop) {
      // make sure it's not `true` which means property wasn't found
      if (neededProperties[prop] !== true) {
        newMixin.properties.push(neededProperties[prop]);
      }
    });
    newMixinDetails.unshift(newMixin);
  });

  return newMixinDetails;
}
function customizeProperties(mixinDetails, propertyInfo) {
  let newMixinDetails = [];
  let neededProperties = {};
  let groups = propertyInfo.groups || [];
  let skipProperties = propertyInfo.skipProperties || [];
  let skipMixins = propertyInfo.skipMixins || [];

  if (groups.length) {
    mixinDetails[0].expand = false;
  }

  groups.forEach(group => {
    group.properties.forEach(prop => {
      neededProperties[prop] = true;
    });
  });

  mixinDetails.forEach(mixin => {
    let newProperties = [];
    mixin.properties.forEach(item => {
      // If 2.10.0 or 2.10.x but < 2.11
      if (compareVersion(VERSION, '2.10.0') === 0 ||
        (compareVersion(VERSION, '2.10.0') === 1 && compareVersion(VERSION, '2.11.0') === -1)) {
        skipProperties = twoTenfilterHack(item.name, skipProperties);
      }
      if (skipProperties.indexOf(item.name) !== -1) {
        return true;
      }

      if (!item.overridden && neededProperties.hasOwnProperty(item.name) && neededProperties[item.name]) {
        neededProperties[item.name] = item;
      } else {
        newProperties.push(item);
      }
    });
    mixin.properties = newProperties;
    if (skipMixins.indexOf(mixin.name) === -1) {
      newMixinDetails.push(mixin);
    }
  });

  groups.slice().reverse().forEach(group => {
    let newMixin = { name: group.name, expand: group.expand, properties: [] };
    group.properties.forEach(function(prop) {
      // make sure it's not `true` which means property wasn't found
      if (neededProperties[prop] !== true) {
        newMixin.properties.push(neededProperties[prop]);
      }
    });
    newMixinDetails.unshift(newMixin);
  });

  return newMixinDetails;
}
function customizeProperties ( mixinDetails , propertyInfo ) { let newMixinDetails = [ ] ; let neededProperties = { } ; let groups = propertyInfo . groups || [ ] ; let skipProperties = propertyInfo . skipProperties || [ ] ; let skipMixins = propertyInfo . skipMixins || [ ] ; if ( groups . length ) { mixinDetails [ 0 ] . expand = false ; } groups . forEach ( group => { group . properties . forEach ( prop => { neededProperties [ prop ] = true ; } ) ; } ) ; mixinDetails . forEach ( mixin => { let newProperties = [ ] ; mixin . properties . forEach ( item => { // If 2.10.0 or 2.10.x but < 2.11 if ( compareVersion ( VERSION , '2.10.0' ) === 0 || ( compareVersion ( VERSION , '2.10.0' ) === 1 && compareVersion ( VERSION , '2.11.0' ) === - 1 ) ) { skipProperties = twoTenfilterHack ( item . name , skipProperties ) ; } if ( skipProperties . indexOf ( item . name ) !== - 1 ) { return true ; } if ( ! item . overridden && neededProperties . hasOwnProperty ( item . name ) && neededProperties [ item . name ] ) { neededProperties [ item . name ] = item ; } else { newProperties . push ( item ) ; } } ) ; mixin . properties = newProperties ; if ( skipMixins . indexOf ( mixin . name ) === - 1 ) { newMixinDetails . push ( mixin ) ; } } ) ; groups . slice ( ) . reverse ( ) . forEach ( group => { let newMixin = { name : group . name , expand : group . expand , properties : [ ] } ; group . properties . forEach ( function ( prop ) { // make sure it's not `true` which means property wasn't found if ( neededProperties [ prop ] !== true ) { newMixin . properties . push ( neededProperties [ prop ] ) ; } } ) ; newMixinDetails . unshift ( newMixin ) ; } ) ; return newMixinDetails ; }
Customizes an object's properties
based on the property `propertyInfo` of
the object's `_debugInfo` method.

Possible options:
- `groups` An array of groups that contains the properties for each group
For example:
```javascript
groups: [
{ name: 'Attributes', properties: ['firstName', 'lastName'] },
{ name: 'Belongs To', properties: ['country'] }
]
```
- `includeOtherProperties` Boolean,
- `true` to include other non-listed properties,
- `false` to only include given properties
- `skipProperties` Array containing list of properties *not* to include
- `skipMixins` Array containing list of mixins *not* to include
- `expensiveProperties` An array of computed properties that are too expensive.
Adding a property to this array makes sure the CP is not calculated automatically.

Example:
```javascript
{
propertyInfo: {
includeOtherProperties: true,
skipProperties: ['toString', 'send', 'withTransaction'],
skipMixins: [ 'Ember.Evented'],
calculate: ['firstName', 'lastName'],
groups: [
{
name: 'Attributes',
properties: [ 'id', 'firstName', 'lastName' ],
expand: true // open by default
},
{
name: 'Belongs To',
properties: [ 'maritalStatus', 'avatar' ],
expand: true
},
{
name: 'Has Many',
properties: [ 'phoneNumbers' ],
expand: true
},
{
name: 'Flags',
properties: ['isLoaded', 'isLoading', 'isNew', 'isDirty']
}
]
}
}
```
Customizes an object s properties based on the property propertyInfo of the object s _debugInfo method .