<commit_before>"use strict";

(function() {

    const cmp = require('./components');

    /*~
     * Utility interface to abstract platform-dependent functionalities.
     */
    class Platform
    {
	debug(msg) {
	    throw new Error('Platform.debug is abstract');
	}
	log(msg) {
	    throw new Error('Platform.log is abstract');
	}
	info(msg) {
	    throw new Error('Platform.info is abstract');
	}
	warn(msg) {
	    throw new Error('Platform.warn is abstract');
	}
	resolve(href, base) {
	    throw new Error('Platform.resolve is abstract');
	}
	read(path) {
	    throw new Error('Platform.read is abstract');
	}
	green(s) {
	    throw new Error('Platform.green is abstract');
	}
	yellow(s) {
	    throw new Error('Platform.yellow is abstract');
	}
	red(s) {
	    throw new Error('Platform.red is abstract');
	}
	bold(s) {
	    throw new Error('Platform.bold is abstract');
	}
	get(url, error, success) {
	    throw new Error('Platform.get is abstract');
	}
	post(url, data, error, success) {
	    throw new Error('Platform.post is abstract');
	}
	put(url, data, error, success) {
	    throw new Error('Platform.put is abstract');
	}
    }

    /*~
     * One space, with its dependencies.
     */
    class Space
    {
        constructor(json)
        {
	    var that = this;
	    this._params    = json.params    || {};
	    this._databases = json.databases || [];
	    this._servers   = json.servers   || [];
	    this._imports   = [];
	    // extract defined values from `obj` and put them in `this.param`
	    var extract = function(obj, props) {
		props.forEach((p) => {
		    var v = obj[p];
		    if ( v !== undefined ) {
			that._params['@' + p] = v;
		    }
		});
	    };
	    // TODO: @srcdir should be initialized automatically to the project
	    // source dir (the subdir src/ in the dir containing xproject/),
	    // @srcdir being just a way to override it (or sometimes to set it,
	    // especially in tests.)
	    extract(json, ['code', 'title', 'srcdir']);
	    if ( json.connect ) {
		extract(json.connect, ['host', 'user', 'password']);
	    }
	}

	addImport(href, space)
	{
	    this._imports.push({
		href  : href,
		space : space
	    });
	}

	param(name)
	{
	    var v = this._params[name];
	    var i = this._imports.length;
	    while ( v === undefined && i > 0 ) {
		v = this._imports[--i].space.param(name);
	    }
	    return v;
	}

	databases()
	{
	    return this._allDbs.map(db => new cmp.Database(db));
	}

	servers()
	{
	    return this._allSrvs.map(srv => new cmp.Server(srv, this));
	}

	// cache databases and servers (resolving import priority)
	cache(platform)
	{
	    var ctxt = {
		href     : "@root",
		dbs      : [],
		dbIds    : {},
		dbNames  : {},
		srvs     : [],
		srvIds   : {},
		srvNames : {}
	    };
	    this.cacheImpl(ctxt, platform);
	    this.messages  = ctxt.infos;
	    this._allDbs   = ctxt.dbs;
	    this._dbIds    = ctxt.dbIds;
	    this._dbNames  = ctxt.dbNames;
	    this._allSrvs  = ctxt.srvs;
	    this._srvIds   = ctxt.srvIds;
	    this._srvNames = ctxt.srvNames;

	    // resolve databases "embedded" in servers
	    var that  = this;
	    var embed = (db) => {
		if ( db.idref ) {
		    if ( Object.keys(db).length > 1 ) {
			throw new Error('DB idref cannot have any other property: '
                            + JSON.stringify(db));
		    }
		    var res = that._dbIds[db.idref];
		    if ( ! res ) {
			throw new Error('DB id:' + db.idref + ' does not exist');
		    }
		    return res;
		}
		else if ( db.nameref ) {
		    if ( Object.keys(db).length > 1 ) {
			throw new Error('DB nameref cannot have any other property: '
                            + JSON.stringify(db));
		    }
		    var res = that._dbNames[db.nameref];
		    if ( ! res ) {
			throw new Error('DB name:' + db.nameref + ' does not exist');
		    }
		    return res;
		}
		else if ( ! db.name && ! db.id ) {
		    throw new Error('DB with no ID and no name in ' + JSON.stringify(db));
		}
		else if ( db.id && that._dbIds[db.id] ) {
		    throw new Error('Embedded DB id:' + db.id + ' already exists');
		}
		else if ( db.name && that._dbNames[db.name] ) {
		    throw new Error('Embedded DB name:' + db.name + ' already exists');
		}
		else {
		    that._allDbs.push(db);
		    if ( db.id ) {
			that._dbIds[db.id] = db;
		    }
		    if ( db.name ) {
			that._dbNames[db.name] = db;
		    }
		    return db;
		}
	    };
	    this._allSrvs.forEach((srv) => {
		if ( srv.content ) {
		    srv.content = embed(srv.content);
		}<commit_msg>No need for a `that` lexical variable.<commit_after>"use strict";

(function() {

    const cmp = require('./components');

    /*~
     * Utility interface to abstract platform-dependent functionalities.
     */
    class Platform
    {
	debug(msg) {
	    throw new Error('Platform.debug is abstract');
	}
	log(msg) {
	    throw new Error('Platform.log is abstract');
	}
	info(msg) {
	    throw new Error('Platform.info is abstract');
	}
	warn(msg) {
	    throw new Error('Platform.warn is abstract');
	}
	resolve(href, base) {
	    throw new Error('Platform.resolve is abstract');
	}
	read(path) {
	    throw new Error('Platform.read is abstract');
	}
	green(s) {
	    throw new Error('Platform.green is abstract');
	}
	yellow(s) {
	    throw new Error('Platform.yellow is abstract');
	}
	red(s) {
	    throw new Error('Platform.red is abstract');
	}
	bold(s) {
	    throw new Error('Platform.bold is abstract');
	}
	get(url, error, success) {
	    throw new Error('Platform.get is abstract');
	}
	post(url, data, error, success) {
	    throw new Error('Platform.post is abstract');
	}
	put(url, data, error, success) {
	    throw new Error('Platform.put is abstract');
	}
    }

    /*~
     * One space, with its dependencies.
     */
    class Space
    {
        constructor(json)
        {
	    var that = this;
	    this._params    = json.params    || {};
	    this._databases = json.databases || [];
	    this._servers   = json.servers   || [];
	    this._imports   = [];
	    // extract defined values from `obj` and put them in `this.param`
	    var extract = function(obj, props) {
		props.forEach((p) => {
		    var v = obj[p];
		    if ( v !== undefined ) {
			that._params['@' + p] = v;
		    }
		});
	    };
	    // TODO: @srcdir should be initialized automatically to the project
	    // source dir (the subdir src/ in the dir containing xproject/),
	    // @srcdir being just a way to override it (or sometimes to set it,
	    // especially in tests.)
	    extract(json, ['code', 'title', 'srcdir']);
	    if ( json.connect ) {
		extract(json.connect, ['host', 'user', 'password']);
	    }
	}

	addImport(href, space)
	{
	    this._imports.push({
		href  : href,
		space : space
	    });
	}

	param(name)
	{
	    var v = this._params[name];
	    var i = this._imports.length;
	    while ( v === undefined && i > 0 ) {
		v = this._imports[--i].space.param(name);
	    }
	    return v;
	}

	databases()
	{
	    return this._allDbs.map(db => new cmp.Database(db));
	}

	servers()
	{
	    return this._allSrvs.map(srv => new cmp.Server(srv, this));
	}

	// cache databases and servers (resolving import priority)
	cache(platform)
	{
	    var ctxt = {
		href     : "@root",
		dbs      : [],
		dbIds    : {},
		dbNames  : {},
		srvs     : [],
		srvIds   : {},
		srvNames : {}
	    };
	    this.cacheImpl(ctxt, platform);
	    this.messages  = ctxt.infos;
	    this._allDbs   = ctxt.dbs;
	    this._dbIds    = ctxt.dbIds;
	    this._dbNames  = ctxt.dbNames;
	    this._allSrvs  = ctxt.srvs;
	    this._srvIds   = ctxt.srvIds;
	    this._srvNames = ctxt.srvNames;

	    // resolve databases "embedded" in databases and servers
	    var embed = (db) => {
		if ( db.idref ) {
		    if ( Object.keys(db).length > 1 ) {
			throw new Error('DB idref cannot have any other property: '
                            + JSON.stringify(db));
		    }
		    var res = this._dbIds[db.idref];
		    if ( ! res ) {
			throw new Error('DB id:' + db.idref + ' does not exist');
		    }
		    return res;
		}
		else if ( db.nameref ) {
		    if ( Object.keys(db).length > 1 ) {
			throw new Error('DB nameref cannot have any other property: '
                            + JSON.stringify(db));
		    }
		    var res = this._dbNames[db.nameref];
		    if ( ! res ) {
			throw new Error('DB name:' + db.nameref + ' does not exist');
		    }
		    return res;
		}
		else if ( ! db.name && ! db.id ) {
		    throw new Error('DB with no ID and no name in ' + JSON.stringify(db));
		}
		else if ( db.id && this._dbIds[db.id] ) {
		    throw new Error('Embedded DB id:' + db.id + ' already exists');
		}
		else if ( db.name && this._dbNames[db.name] ) {
		    throw new Error('Embedded DB name:' + db.name + ' already exists');
		}
		else {
		    this._allDbs.push(db);
		    if ( db.id ) {
			this._dbIds[db.id] = db;
		    }
		    if ( db.name ) {
			this._dbNames[db.name] = db;
		    }
		    return db;
		}
	    };
	    this._allSrvs.forEach((srv) => {
		if ( srv.content ) {
		    srv.content = embed(srv.content);
		}
{'fraction_non_alphanumeric': 0.1512894619831036, 'fraction_numerical': 0.0006669630947087594, 'mean_word_length': 2.1701902748414374, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, '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': '3568883', 'n_tokens_mistral': 3367, 'n_tokens_neox': 3034, 'n_words': 777}