text: import warning from 'tiny-warning';
  
  /* eslint-disable no-use-before-define */
  
  var isObject = function isObject(obj) {
    return obj && typeof obj === 'object' && !Array.isArray(obj);
  };
  
  var valueNs = "extendCurrValue" + Date.now();
  
  function mergeExtend(style, rule, sheet, newStyle) {
    var extendType = typeof style.extend; // Extend using a rule name.
  
    if (extendType === 'string') {
      if (!sheet) return;
      var refRule = sheet.getRule(style.extend);
      if (!refRule) return;
  
      if (refRule === rule) {
        process.env.NODE_ENV !== "production" ? warning(false, "[JSS] A rule tries to extend itself \n" + rule.toString()) : void 0;
        return;
      }
  
      var parent = refRule.options.parent;
  
      if (parent) {
        var originalStyle = parent.rules.raw[style.extend];
        extend(originalStyle, rule, sheet, newStyle);
      }
  
      return;
    } // Extend using an array of objects.
  
  
    if (Array.isArray(style.extend)) {
      for (var index = 0; index < style.extend.length; index++) {
        extend(style.extend[index], rule, sheet, newStyle);
      }
  
      return;
    } // Extend is a style object.
  
  
    for (var prop in style.extend) {
      if (prop === 'extend') {
        extend(style.extend.extend, rule, sheet, newStyle);
        continue;
      }
  
      if (isObject(style.extend[prop])) {
        if (!(prop in newStyle)) newStyle[prop] = {};
        extend(style.extend[prop], rule, sheet, newStyle[prop]);
        continue;
      }
  
      newStyle[prop] = style.extend[prop];
    }
  }
  
  function mergeRest(style, rule, sheet, newStyle) {
    // Copy base style.
    for (var prop in style) {
      if (prop === 'extend') continue;
  
      if (isObject(newStyle[prop]) && isObject(style[prop])) {
        extend(style[prop], rule, sheet, newStyle[prop]);
        continue;
      }
  
      if (isObject(style[prop])) {
        newStyle[prop] = extend(style[prop], rule, sheet);
        continue;
      }
  
      newStyle[prop] = style[prop];
    }
  }
  /**
   * Recursively extend styles.
   */
  
  
  function extend(style, rule, sheet, newStyle) {
    if (newStyle === void 0) {
      newStyle = {};
    }
  
    mergeExtend(style, rule, sheet, newStyle);
    mergeRest(style, rule, sheet, newStyle);
    return newStyle;
  }
  /**
   * Handle `extend` property.
   *
   * @param {Rule} rule
   * @api public
   */
  
  
  function jssExtend() {
    function onProcessStyle(style, rule, sheet) {
      if ('extend' in style) return extend(style, rule, sheet);
      return style;
    }
  
    function onChangeValue(value, prop, rule) {
      if (prop !== 'extend') return value; // Value is empty, remove properties set previously.
  
      if (value == null || value === false) {
        // $FlowFixMe: Flow complains because there is no indexer property in StyleRule
        for (var key in rule[valueNs]) {
          rule.prop(key, null);
        } // $FlowFixMe: Flow complains because there is no indexer property in StyleRule
  
  
        rule[valueNs] = null;
        return null;
      }
  
      if (typeof value === 'object') {
        // $FlowFixMe: This will be an object
        for (var _key in value) {
          rule.prop(_key, value[_key]);
        } // $FlowFixMe: Flow complains because there is no indexer property in StyleRule
  
  
        rule[valueNs] = value;
      } // Make sure we don't set the value in the core.
  
  
      return null;
    }
  
    return {
      onProcessStyle: onProcessStyle,
      onChangeValue: onChangeValue
    };
  }
  
  export default jssExtend;
  