<commit_before>CLASS({
  package: 'foam.ui',

  name: 'Window',

  exports: [
    '$$',
    '$',
    'addStyle',
    'animate',
    'cancelAnimationFrame'
    'clearInterval',
    'clearTimeout',
    'console',
    'document',
    'dynamic',
    'error',
    'info',
    'log',
    'memento',
    'registerModel_',
    'requestAnimationFrame',
    'setInterval',
    'setTimeout',
    'warn',
    'window'
  ],

  properties: [
    {
      model_: 'StringProperty',
      name: 'name',
      defaultValue: 'window'
    },
    {
      name: 'window',
      postSet: function(_, w) {
        // TODO: This would be better if ChromeApp.js added this behaviour
        // in a SubModel of Window, ie. ChromeAppWindow
        if ( this.X.subDocument ) this.X.subDocument(w.document);

        return w.document;
      }
    },
    {
      name: 'document'
    },
    {
      name: 'installedModels',
      lazyFactory: function() {
        return this.documentinstalledModels || this.document.installedModels = {};
      }
    },
    {
      model_: 'BooleanProperty',
      name: 'isBackground',
      defaultValue: false
    },
    {
      name: 'console',
      lazyFactory: function() { return this.window.console; }
    },
    {
      name: 'memento',
      lazyFactory: function() { this.window.WindowHashValue.create({window: this.window}); }
    }
  ],

  methods: {
    registerModel_: function(model) {
      var X        = this.X;
      var document = this.document;

      // TODO(kgr): If Traits have CSS then it will get installed more than once.
      // TODO(kgr): Add package support.
      for ( var m = model ; m && m.getPrototype ; m = m.extendsModel && this[m.extendsModel] ) {
        if ( this.installedModels[m.id] ) return;
        this.installedModels[m.id] = true;
        arequireModel(m)(function(m) {
          m.getPrototype().installInDocument(X, document);
        });
      }
    },
    addStyle: function(css) {
      var s = this.document.createElement('style');
      s.innerHTML = css;
      this.document.head.appendChild(s);
    },
    log:   function() { this.console.log.apply(this.console, arguments); }, 
    warn:  function() { this.console.warn.apply(this.console, arguments); }, 
    info:  function() { this.console.info.apply(this.console, arguments); }, 
    error: function() { this.console.error.apply(this.console, arguments); }, 
    $: function(id) {
      return ( this.document.FOAM_OBJECTS && this.document.FOAM_OBJECTS[id] ) ?
        this.document.FOAM_OBJECTS[id] :
        this.document.getElementById(id);
    },
    $$: function(cls) {
      return this.document.getElementsByClassName(cls);
    },
    dynamic: function(fn, opt_fn) {
      Events.dynamic(fn, opt_fn, this.X);
    },
    animate: function(duration, fn, opt_interp, opt_onEnd) {
      return Movement.animate(duration, fn, opt_interp, opt_onEnd, this.X);
    },
    setTimeout: function(f, t) {
      return this.window.setTimeout.apply(this.window, arguments);
    },
    clearTimeout: function(id) { this.window.clearTimeout(id); },
    setInterval: function(f, t) {
      return this.window.setInterval.apply(this.window, arguments);
    },
    clearInterval: function(id) { this.window.clearInterval(id); },
    requestAnimationFrame: function(f) {
      console.assert(
        this.window.requestAnimationFrame,
        'requestAnimationFrame not defined');
      return this.window.requestAnimationFrame(f);
    },
    cancelAnimationFrame: function(id) {
      this.window.cancelAnimationFrame && this.window.cancelAnimationFrame(id);
    }
  }
});<commit_msg>Bug fixes.<commit_after>CLASS({
  package: 'foam.ui',

  name: 'Window',

  exports: [
    '$$',
    '$',
    'addStyle',
    'animate',
    'cancelAnimationFrame',
    'clearInterval',
    'clearTimeout',
    'console',
    'document',
    'dynamic',
    'error',
    'info',
    'log',
    'memento',
    'registerModel_',
    'requestAnimationFrame',
    'setInterval',
    'setTimeout',
    'warn',
    'window'
  ],

  properties: [
    {
      model_: 'StringProperty',
      name: 'name',
      defaultValue: 'window'
    },
    {
      name: 'window',
      postSet: function(_, w) {
        // TODO: This would be better if ChromeApp.js added this behaviour
        // in a SubModel of Window, ie. ChromeAppWindow
        if ( this.X.subDocument ) this.X.subDocument(w.document);

        return w.document;
      }
    },
    {
      name: 'document'
    },
    {
      name: 'installedModels',
      lazyFactory: function() {
        return this.document.installedModels || ( this.document.installedModels = {} );
      }
    },
    {
      model_: 'BooleanProperty',
      name: 'isBackground',
      defaultValue: false
    },
    {
      name: 'console',
      lazyFactory: function() { return this.window.console; }
    },
    {
      name: 'memento',
      lazyFactory: function() { this.window.WindowHashValue.create({window: this.window}); }
    }
  ],

  methods: {
    registerModel_: function(model) {
      var X        = this.X;
      var document = this.document;

      // TODO(kgr): If Traits have CSS then it will get installed more than once.
      // TODO(kgr): Add package support.
      for ( var m = model ; m && m.getPrototype ; m = m.extendsModel && this[m.extendsModel] ) {
        if ( this.installedModels[m.id] ) return;
        this.installedModels[m.id] = true;
        arequireModel(m)(function(m) {
          m.getPrototype().installInDocument(X, document);
        });
      }
    },
    addStyle: function(css) {
      var s = this.document.createElement('style');
      s.innerHTML = css;
      this.document.head.appendChild(s);
    },
    log:   function() { this.console.log.apply(this.console, arguments); }, 
    warn:  function() { this.console.warn.apply(this.console, arguments); }, 
    info:  function() { this.console.info.apply(this.console, arguments); }, 
    error: function() { this.console.error.apply(this.console, arguments); }, 
    $: function(id) {
      return ( this.document.FOAM_OBJECTS && this.document.FOAM_OBJECTS[id] ) ?
        this.document.FOAM_OBJECTS[id] :
        this.document.getElementById(id);
    },
    $$: function(cls) {
      return this.document.getElementsByClassName(cls);
    },
    dynamic: function(fn, opt_fn) {
      Events.dynamic(fn, opt_fn, this.X);
    },
    animate: function(duration, fn, opt_interp, opt_onEnd) {
      return Movement.animate(duration, fn, opt_interp, opt_onEnd, this.X);
    },
    setTimeout: function(f, t) {
      return this.window.setTimeout.apply(this.window, arguments);
    },
    clearTimeout: function(id) { this.window.clearTimeout(id); },
    setInterval: function(f, t) {
      return this.window.setInterval.apply(this.window, arguments);
    },
    clearInterval: function(id) { this.window.clearInterval(id); },
    requestAnimationFrame: function(f) {
      console.assert(
        this.window.requestAnimationFrame,
        'requestAnimationFrame not defined');
      return this.window.requestAnimationFrame(f);
    },
    cancelAnimationFrame: function(id) {
      this.window.cancelAnimationFrame && this.window.cancelAnimationFrame(id);
    }
  }
});


// Using the existence of 'process' to determine that we're running in Node.
X = this.subWindow(
  window,
  'DEFAULT WINDOW',
  typeof process === 'object').sub({IN_WINDOW: false}, 'TOP-X');

{'fraction_non_alphanumeric': 0.14558504875406283, 'fraction_numerical': 0.0, 'mean_word_length': 2.5954235637779943, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '5859922', 'n_tokens_mistral': 2309, 'n_tokens_neox': 2272, 'n_words': 441}