<commit_before>import {parse_ioptions} from './options';
import {
  compose,
  diff_arrays,
  is_empty,
  is_function,
  is_object,
  is_plain_object,
} from './utility';


const USAGE = (target?): string => {
  return `Expected non-null object or function, got ${target}`;
};

interface IMixJoint {
  method: Function;
  advice: Function;
  key: string;
}

export var mix = function(target, mixin: IMixin, options: IMixOptions = {}) {
  if (target === undefined) {
    throw new TypeError(USAGE());
  } else if (!(is_function(target) || is_object(target))) {
    throw new TypeError(USAGE(target));
  }
  if (!is_plain_object(mixin)) {
    throw new TypeError('Expected mixin to be an object literal');
  }
  let {
    pre_method_advice, post_method_advice,
    pre_mixing_hook, post_mixing_hook,
    omit,
  } = parse_ioptions(options, mixin);
  let keys_to_mix_in = diff_arrays(
    Object.getOwnPropertyNames(mixin).filter(key => {
      return (mixin[key] !== pre_mixing_hook) && (mixin[key] !== post_mixing_hook);
    }),
    omit);
  if (is_empty(keys_to_mix_in)) {
    throw new Error('All mixin keys have been omitted!');
  }
  pre_mixing_hook.call(mixin, target);
  let mix_joints: IMixJoint[] = [];
  keys_to_mix_in.forEach((key: string) => {
    let advice = pre_method_advice[key] || post_method_advice[key];
    if (advice) {
      // defer binding the composite methods until
      // after all other data/behavior have been mixed in
      mix_joints.push({
        advice,
        method: mixin[key],
        key: key,
      });
    } else  {
      target[key] = mixin[key];
    }
  });
  mix_joints.forEach(composite => {
    let {advice, method, key} = composite;
    if (pre_method_advice[key]) {
      target[key] = compose(method, advice, target);
    } else if (post_method_advice[key]) {
      target[key] = compose(advice, method, target);
    }
  });
  post_mixing_hook.call(mixin, target);
  return target;
};
<commit_msg>adding comments to a blob<commit_after>import {parse_ioptions} from './options';
import {
  compose,
  diff_arrays,
  is_empty,
  is_function,
  is_object,
  is_plain_object,
} from './utility';


const USAGE = (target?): string => {
  return `Expected non-null object or function, got ${target}`;
};

interface IMixJoint {
  method: Function;
  advice: Function;
  key: string;
}

export var mix = function(target, mixin: IMixin, options: IMixOptions = {}) {
  ////////////////////////////
  // setup & pre-mixing checks
  if (target === undefined) {
    throw new TypeError(USAGE());
  } else if (!(is_function(target) || is_object(target))) {
    throw new TypeError(USAGE(target));
  }
  if (!is_plain_object(mixin)) {
    throw new TypeError('Expected mixin to be an object literal');
  }
  let {
    pre_method_advice, post_method_advice,
    pre_mixing_hook, post_mixing_hook,
    omit,
  } = parse_ioptions(options, mixin);
  let keys_to_mix_in = diff_arrays(
    Object.getOwnPropertyNames(mixin).filter(key => {
      return (mixin[key] !== pre_mixing_hook) && (mixin[key] !== post_mixing_hook);
    }),
    omit);
  if (is_empty(keys_to_mix_in)) {
    throw new Error('All mixin keys have been omitted!');
  }

  ////////////////////
  // initialize mixing
  pre_mixing_hook.call(mixin, target);

  //////////////
  // perform mix
  let mix_joints: IMixJoint[] = [];
  keys_to_mix_in.forEach((key: string) => {
    let advice = pre_method_advice[key] || post_method_advice[key];
    if (advice) {
      // defer attaching advice until all other
      // data/behavior have been mixed in
      mix_joints.push({key, advice, method: mixin[key]});
    } else  {
      target[key] = mixin[key];
    }
  });
  mix_joints.forEach(composite => {
    // attach advice now
    let {advice, method, key} = composite;
    if (pre_method_advice[key]) {
      target[key] = compose(method, advice, target);
    } else if (post_method_advice[key]) {
      target[key] = compose(advice, method, target);
    }
  });

  //////////////////
  // finalize mixing
  post_mixing_hook.call(mixin, target);
  return target;
};

{'fraction_non_alphanumeric': 0.15456559192714742, 'fraction_numerical': 0.0, 'mean_word_length': 3.194014447884417, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, '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': '4499281', 'n_tokens_mistral': 1406, 'n_tokens_neox': 1386, 'n_words': 315}