From 43c0d24720933b6b6f8b0cd89bc1c3ddc6993ad2 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 11:12:29 +1000 Subject: [PATCH 01/42] added tests that need to pass after restructuring. --- test/array_object_types.test.js | 85 +++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 test/array_object_types.test.js diff --git a/test/array_object_types.test.js b/test/array_object_types.test.js new file mode 100644 index 0000000..dc511c1 --- /dev/null +++ b/test/array_object_types.test.js @@ -0,0 +1,85 @@ +var getSchema = require('../'); +var assert = require('assert'); +var _ = require('lodash'); + + +describe('arrays and objects as type (INT-203 restructuring)', function () { + var docs = [ + { x: [1, 2, 3] }, + { x: "foo" }, + { x: { b: 1 } }, + { x: [ "bar", null, false ] }, + { x: [ {c: 1, d: 1}, {c: 2 } ] }, + { e: 1 } + ]; + + var schema; + + before(function (done) { + schema = getSchema('mixed.mess', docs, done); + }); + + describe('Field', function () { + it('have the right type distribution of x', function() { + var dist = _.zipObject( + schema.fields.get('x').types.pluck('name'), + schema.fields.get('x').types.pluck('probability') + ); + assert.deepEqual(dist, { + 'Array': 3/6, + 'String': 1/6, + 'Object': 1/6, + 'Undefined': 1/6 + }); + }); + + it('should contain the basic values of x at Field level', function() { + assert.deepEqual(schema.fields.get('x').values.serialize(), ["foo"]); + }); + + it('should have an `.fields` alias for convenience', function() { + assert.deepEqual(schema.fields.get('x').fields, schema.fields.get('x').types.get('Object').fields); + }); + }); + + + describe('Nested Array', function () { + var arr; + + before(function () { + arr = schema.fields.get('x').types.get('Array'); + }); + + it('should return the lengths of all encountered arrays', function () { + assert.deepEqual(arr.lengths, [3, 3, 2]); + }); + + it('should return the type distribution inside an array', function () { + var arrDist = _.zipObject( + arr.types.pluck('name'), + arr.types.pluck('probability') + ); + assert.deepEqual(arrDist, { + 'Number': 3/8, + 'String': 1/8, + 'Null': 1/8, + 'Boolean': 1/8, + 'Object': 2/8 + }); + }); + + it('should return the correct count inside the array', function () { + assert.equal(arr.count, 8); + }); + + it('should contain the basic values inside the array', function () { + assert.deepEqual(arr.values.serialize(), [1, 2, 3, 'foo', null, false]); + }); + + it('should have a `.fields` alias for convenience', function () { + assert.deepEqual(arr.fields, arr.types.get('Object').fields); + }); + + }); + +}); From 709988cf951c60dde5412769398b2b18b4079916 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 11:13:30 +1000 Subject: [PATCH 02/42] renamed to use slugcase instead of underscores. --- test/{array_object_types.test.js => array-object-types.test.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{array_object_types.test.js => array-object-types.test.js} (100%) diff --git a/test/array_object_types.test.js b/test/array-object-types.test.js similarity index 100% rename from test/array_object_types.test.js rename to test/array-object-types.test.js From bfeda655730a6d5effd1d42aa75919aee4a804be Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 11:15:11 +1000 Subject: [PATCH 03/42] defined x once for readability. --- test/array_object_types.test.js | 91 +++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 test/array_object_types.test.js diff --git a/test/array_object_types.test.js b/test/array_object_types.test.js new file mode 100644 index 0000000..c1a649a --- /dev/null +++ b/test/array_object_types.test.js @@ -0,0 +1,91 @@ +var getSchema = require('../'); +var assert = require('assert'); +var _ = require('lodash'); + + +describe('arrays and objects as type (INT-203 restructuring)', function () { + var docs = [ + { x: [1, 2, 3] }, + { x: "foo" }, + { x: { b: 1 } }, + { x: [ "bar", null, false ] }, + { x: [ {c: 1, d: 1}, {c: 2 } ] }, + { e: 1 } + ]; + + var schema; + + before(function (done) { + schema = getSchema('mixed.mess', docs, done); + }); + + describe('Field', function () { + var x; + + before(function () { + x = schema.fields.get('x'); + }); + + it('have the right type distribution of x', function() { + var dist = _.zipObject( + x.types.pluck('name'), + x.types.pluck('probability') + ); + assert.deepEqual(dist, { + 'Array': 3/6, + 'String': 1/6, + 'Object': 1/6, + 'Undefined': 1/6 + }); + }); + + it('should contain the basic values of x at Field level', function() { + assert.deepEqual(x.values.serialize(), ["foo"]); + }); + + it('should have an `.fields` alias for convenience', function() { + assert.deepEqual(x.fields, x.types.get('Object').fields); + }); + }); + + + describe('Nested Array', function () { + var arr; + + before(function () { + arr = schema.fields.get('x').types.get('Array'); + }); + + it('should return the lengths of all encountered arrays', function () { + assert.deepEqual(arr.lengths, [3, 3, 2]); + }); + + it('should return the type distribution inside an array', function () { + var arrDist = _.zipObject( + arr.types.pluck('name'), + arr.types.pluck('probability') + ); + assert.deepEqual(arrDist, { + 'Number': 3/8, + 'String': 1/8, + 'Null': 1/8, + 'Boolean': 1/8, + 'Object': 2/8 + }); + }); + + it('should return the correct count inside the array', function () { + assert.equal(arr.count, 8); + }); + + it('should contain the basic values inside the array', function () { + assert.deepEqual(arr.values.serialize(), [1, 2, 3, 'foo', null, false]); + }); + + it('should have a `.fields` alias for convenience', function () { + assert.deepEqual(arr.fields, arr.types.get('Object').fields); + }); + + }); + +}); From 4bdd7fe18cd51e9a988016b47c72f021efd6baf5 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 11:16:45 +1000 Subject: [PATCH 04/42] defined x once for readability. --- test/array-object-types.test.js | 14 +++-- test/array_object_types.test.js | 91 --------------------------------- 2 files changed, 10 insertions(+), 95 deletions(-) delete mode 100644 test/array_object_types.test.js diff --git a/test/array-object-types.test.js b/test/array-object-types.test.js index dc511c1..c1a649a 100644 --- a/test/array-object-types.test.js +++ b/test/array-object-types.test.js @@ -20,10 +20,16 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { }); describe('Field', function () { + var x; + + before(function () { + x = schema.fields.get('x'); + }); + it('have the right type distribution of x', function() { var dist = _.zipObject( - schema.fields.get('x').types.pluck('name'), - schema.fields.get('x').types.pluck('probability') + x.types.pluck('name'), + x.types.pluck('probability') ); assert.deepEqual(dist, { 'Array': 3/6, @@ -34,11 +40,11 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { }); it('should contain the basic values of x at Field level', function() { - assert.deepEqual(schema.fields.get('x').values.serialize(), ["foo"]); + assert.deepEqual(x.values.serialize(), ["foo"]); }); it('should have an `.fields` alias for convenience', function() { - assert.deepEqual(schema.fields.get('x').fields, schema.fields.get('x').types.get('Object').fields); + assert.deepEqual(x.fields, x.types.get('Object').fields); }); }); diff --git a/test/array_object_types.test.js b/test/array_object_types.test.js deleted file mode 100644 index c1a649a..0000000 --- a/test/array_object_types.test.js +++ /dev/null @@ -1,91 +0,0 @@ -var getSchema = require('../'); -var assert = require('assert'); -var _ = require('lodash'); - - -describe('arrays and objects as type (INT-203 restructuring)', function () { - var docs = [ - { x: [1, 2, 3] }, - { x: "foo" }, - { x: { b: 1 } }, - { x: [ "bar", null, false ] }, - { x: [ {c: 1, d: 1}, {c: 2 } ] }, - { e: 1 } - ]; - - var schema; - - before(function (done) { - schema = getSchema('mixed.mess', docs, done); - }); - - describe('Field', function () { - var x; - - before(function () { - x = schema.fields.get('x'); - }); - - it('have the right type distribution of x', function() { - var dist = _.zipObject( - x.types.pluck('name'), - x.types.pluck('probability') - ); - assert.deepEqual(dist, { - 'Array': 3/6, - 'String': 1/6, - 'Object': 1/6, - 'Undefined': 1/6 - }); - }); - - it('should contain the basic values of x at Field level', function() { - assert.deepEqual(x.values.serialize(), ["foo"]); - }); - - it('should have an `.fields` alias for convenience', function() { - assert.deepEqual(x.fields, x.types.get('Object').fields); - }); - }); - - - describe('Nested Array', function () { - var arr; - - before(function () { - arr = schema.fields.get('x').types.get('Array'); - }); - - it('should return the lengths of all encountered arrays', function () { - assert.deepEqual(arr.lengths, [3, 3, 2]); - }); - - it('should return the type distribution inside an array', function () { - var arrDist = _.zipObject( - arr.types.pluck('name'), - arr.types.pluck('probability') - ); - assert.deepEqual(arrDist, { - 'Number': 3/8, - 'String': 1/8, - 'Null': 1/8, - 'Boolean': 1/8, - 'Object': 2/8 - }); - }); - - it('should return the correct count inside the array', function () { - assert.equal(arr.count, 8); - }); - - it('should contain the basic values inside the array', function () { - assert.deepEqual(arr.values.serialize(), [1, 2, 3, 'foo', null, false]); - }); - - it('should have a `.fields` alias for convenience', function () { - assert.deepEqual(arr.fields, arr.types.get('Object').fields); - }); - - }); - -}); From 8af98a2347dbe69aea18bdf8e6db1be26f98b813 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 17:06:25 +1000 Subject: [PATCH 05/42] intermediate checkin, WIP --- lib/field-collection.js | 26 ++++- lib/field.js | 166 +++++++++++++---------------- lib/parser.js | 146 +++++++++++++------------- lib/schema.js | 10 +- lib/type-collection.js | 49 +++++++-- lib/type.js | 190 +++++++++++++++++++++++++++------- lib/value-collection.js | 1 + lib/value.js | 1 + test/type-collection.test.js | 71 +++++++++++++ test/type.test.js | 60 +++++++++++ test/value-collection.test.js | 22 ++++ 11 files changed, 530 insertions(+), 212 deletions(-) create mode 100644 test/type-collection.test.js create mode 100644 test/type.test.js create mode 100644 test/value-collection.test.js diff --git a/lib/field-collection.js b/lib/field-collection.js index 8ff84fa..ed3744d 100644 --- a/lib/field-collection.js +++ b/lib/field-collection.js @@ -1,11 +1,15 @@ var Collection = require('ampersand-collection'); var lodashMixin = require('ampersand-collection-lodash-mixin'); +var Field = require('./field'); +var debug = require('debug')('mongodb-schema:field-collection'); /** * Container for a list of Fields. */ var FieldCollection = Collection.extend(lodashMixin, { + className: 'FieldCollection', mainIndex: 'name', + model: Field, comparator: function (a, b) { // make sure _id is always at top, even in presence of uppercase fields var aId = a.getId(); @@ -15,8 +19,26 @@ var FieldCollection = Collection.extend(lodashMixin, { // otherwise sort case-insensitively return (aId.toLowerCase() < bId.toLowerCase()) ? -1 : 1; }, - model: function(attrs, options) { - return new attrs.klass(attrs, options); + /** + * adds a new name/value pair to the correct field, and creates the + * field first if it doesn't exist yet. Leave it to field.types to + * add the value. + * + * @param {String} name name of the field + * @param {Any} value value to be added + */ + addToField: function (name, value) { + // get or create field + var field = this.get(name); + if (!field) { + field = this.add({ + name: name, + parent: this.parent + }); + } + field.count += 1; + field.types.addToType(value); } }); + module.exports = FieldCollection; diff --git a/lib/field.js b/lib/field.js index 6b9cfee..667cf52 100644 --- a/lib/field.js +++ b/lib/field.js @@ -2,13 +2,13 @@ var _ = require('lodash'); var State = require('ampersand-state'); var TypeCollection = require('./type-collection'); var ValueCollection = require('./value-collection'); -var FieldCollection = require('./field-collection'); var debug = require('debug')('mongodb-schema:field'); /** * Describes a single field in the schema based on sampled values. */ -var Field = State.extend({ +module.exports = State.extend({ + className: 'Field', idAttribute: 'name', props: { /** @@ -28,10 +28,10 @@ var Field = State.extend({ /** * Probability of this field being set. */ - probability: { - type: 'number', - default: 0 - }, + // probability: { + // type: 'number', + // default: 0 + // }, /** * Number of unique values seen. */ @@ -84,6 +84,13 @@ var Field = State.extend({ return this.types.pluck('name'); } }, + probability: { + deps: ['types.length'], + fn: function () { + debug('count', this.count, 'parent', this.parent.className, 'pcount', this.parent.count); + return this.count / this.parent.count; + } + }, /** * The total number of documents we would see if always set. * This differs from `#count` as it is the value used to calculate @@ -109,6 +116,18 @@ var Field = State.extend({ fn: function() { return this.unique < this.count; } + }, + /** + * Convenience alias to access sub-fields. Returns + * null if this Field does not have a 'Document' type. + * @returns {FieldCollection} + */ + fields: { + deps: ['types.length'], + fn: function() { + var objType = this.types.get('Document'); + return objType ? objType.fields : null; + } } }, collections: { @@ -119,11 +138,7 @@ var Field = State.extend({ /** * A sample of values seen for this field. */ - values: ValueCollection, - /** - * Child fields. - */ - fields: FieldCollection + values: ValueCollection }, /** * @constructs Field @@ -150,9 +165,11 @@ var Field = State.extend({ * the `type` property to be recalculated correctly. */ this.trigger('change:types.length'); - this.listenTo(type.values, 'add', this.onValueAdded); - this.listenTo(type.values, 'remove', this.onValueRemoved); - this.listenTo(type.values, 'reset', this.onValueReset); + if (type.values) { + this.listenTo(type.values, 'add', this.onValueAdded); + this.listenTo(type.values, 'remove', this.onValueRemoved); + this.listenTo(type.values, 'reset', this.onValueReset); + } }, /** * @see Schema#onTypeAdded @@ -163,9 +180,11 @@ var Field = State.extend({ */ onTypeRemoved: function(type) { this.trigger('change:types.length'); - this.stopListening(type.values, 'add', this.onValueAdded); - this.stopListening(type.values, 'remove', this.onValueRemoved); - this.stopListening(type.values, 'reset', this.onValueReset); + if (type.values) { + this.stopListening(type.values, 'add', this.onValueAdded); + this.stopListening(type.values, 'remove', this.onValueRemoved); + this.stopListening(type.values, 'reset', this.onValueReset); + } }, onTypeReset: function() { this.trigger('change:types.length'); @@ -194,45 +213,45 @@ var Field = State.extend({ * and make sure all of our child collections are nicely sorted. * If we have any subfields, call `commit()` on each of those as well. */ - commit: function() { - var newprob; - newprob = this.count / this.parent.count; - if (newprob !== this.probability) { - this.probability = newprob; - } - var undef = this.types.get('Undefined'); - if ((this.total - this.count) <= 0) { - if(undef){ - debug('removing extraneous Undefined for `%s`', this.getId()); - this.types.remove({ - name: 'Undefined' - }); - } - // No undefined types to manage - } else { - if (!undef) { - debug('adding Undefined for `%s`', this.getId()); - undef = this.types.add({ - name: 'Undefined', - unique: 1 - }); - } - undef.count = (this.total - this.count); - undef.probability = (undef.count - this.count); - } - this.types.map(function(type) { - type.probability = type.count / this.total; - type.unique = _.unique(type.values.pluck('value')).length; - }.bind(this)); - this.unique = _.sum(this.types.pluck('unique')); - this.types.sort(); + // commit: function() { + // var newprob; + // newprob = this.count / this.parent.count; + // if (newprob !== this.probability) { + // this.probability = newprob; + // } + // var undef = this.types.get('Undefined'); + // if ((this.total - this.count) <= 0) { + // if(undef){ + // debug('removing extraneous Undefined for `%s`', this.getId()); + // this.types.remove({ + // name: 'Undefined' + // }); + // } + // // No undefined types to manage + // } else { + // if (!undef) { + // debug('adding Undefined for `%s`', this.getId()); + // undef = this.types.add({ + // name: 'Undefined', + // unique: 1 + // }); + // } + // undef.count = (this.total - this.count); + // undef.probability = (undef.count - this.count); + // } + // this.types.map(function(type) { + // type.probability = type.count / this.total; + // type.unique = _.unique(type.values.pluck('value')).length; + // }.bind(this)); + // this.unique = _.sum(this.types.pluck('unique')); + // this.types.sort(); - if (this.fields.length > 0) { - this.fields.map(function(field) { - field.commit(); - }); - } - }, + // if (this.fields.length > 0) { + // this.fields.map(function(field) { + // field.commit(); + // }); + // } + // }, serialize: function() { var res = this.getAttributes({ props: true, @@ -247,42 +266,5 @@ var Field = State.extend({ return res; }, }); -module.exports = Field; -/** - * A basic field has no descendant fields, such as `String`, `ObjectID`, - * `Boolean`, or `Date`. - */ -module.exports.Basic = Field.extend({}); -module.exports.EmbeddedArray = Field.extend({ - props: { - type: { - type: 'string', - default: 'Array' - }, - lengths: { - type: 'array', - default: function() { - return []; - } - } - }, - derived: { - average_length: { - deps: ['lengths'], - fn: function() { - return _.sum(this.lengths) / this.lengths.length; - } - } - } -}); - -module.exports.EmbeddedDocument = Field.extend({ - props: { - type: { - type: 'string', - default: 'Object' - } - } -}); diff --git a/lib/parser.js b/lib/parser.js index 656c10a..360c9a5 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -1,82 +1,84 @@ -var _ = require('lodash'); -var getTypeName = require('./type').getNameFromValue; -var Field = require('./field'); +// var _ = require('lodash'); -function onFieldSampled(schema, name, value) { - var typeName = getTypeName(value); - if (typeName === 'Array') { - onEmbeddedArray(schema, name, typeName, value); - } else if (typeName === 'Object') { - onEmbeddedDocument(schema, name, typeName, value); - } else { - onBasicField(schema, name, typeName, value); - } -} +// var getTypeName = module.exports.getTypeName = function (value) { +// var T; +// if (_.has(value, '_bsontype')) { +// T = value._bsontype; +// } else { +// T = Object.prototype.toString.call(value).replace(/\[object (\w+)\]/, '$1'); +// } +// // don't want to create naming conflict with javascript Object +// if (T === 'Object') T = 'Document'; +// return T; +// }; -function onBasicField(schema, name, typeName, value) { - var field = schema.fields.get(name); - if (!field) { - field = schema.fields.add({ - name: name, - klass: Field.Basic, - parent: schema - }); - } - field.count += 1; +// var addValueToType = module.exports.addValueToTypes = function (types, value) { +// var typeName = getTypeName(value); +// // get or create type +// var type = types.get(typeName); +// if (!type) { +// type = types.add({ +// name: typeName +// }); +// } +// type.count += 1; +// // leave it to type to add the value +// type.addValue(value); +// }; - var type = field.types.get(typeName); - if (!type) { - type = field.types.add({ - name: typeName, - }); - } - type.count += 1; +// module.exports.addValueToFields = function(schema, name, value) { +// // get or create field +// var field = schema.fields.get(name); +// if (!field) { +// field = schema.fields.add({ +// name: name, +// parent: schema +// }); +// } +// field.count += 1; - type.values.add({ - value: value - }); -} +// addValueToType(field.types, value); +// }; -function onEmbeddedArray(schema, name, typeName, value) { - var field = schema.fields.get(name); - if (!field) { - field = schema.fields.add({ - name: name, - klass: Field.EmbeddedArray, - parent: schema - }); - } +// function onEmbeddedArray(schema, name, typeName, value) { +// var field = schema.fields.get(name); - field.count += 1; - field.lengths.push(value.length); - field.trigger('change:lengths'); - _.each(value, function(d) { - var typeName = getTypeName(d); - if (typeName === 'Object') { - _.each(d, function(val, key) { - onBasicField(field, key, getTypeName(val), val); - }); - } else { - onBasicField(field, '__basic__', typeName, d); - } - }); -} +// if (!field) { +// field = schema.fields.add({ +// name: name, +// klass: Field.EmbeddedArray, +// parent: schema +// }); +// } -function onEmbeddedDocument(schema, name, typeName, value) { - var field = schema.fields.get(name); +// field.count += 1; +// field.lengths.push(value.length); +// field.trigger('change:lengths'); +// _.each(value, function(d) { +// var typeName = getTypeName(d); +// if (typeName === 'Object') { +// _.each(d, function(val, key) { +// onBasicField(field, key, getTypeName(val), val); +// }); +// } else { +// onBasicField(field, '__basic__', typeName, d); +// } +// }); +// } - if (!field) { - field = schema.fields.add({ - name: name, - klass: Field.EmbeddedDocument, - parent: schema - }); - } - field.count += 1; - _.each(value, function(val, key) { - onFieldSampled(field, key, val); - }); -} +// function onEmbeddedDocument(schema, name, typeName, value) { +// var field = schema.fields.get(name); -module.exports.parse = onFieldSampled; +// if (!field) { +// field = schema.fields.add({ +// name: name, +// klass: Field.EmbeddedDocument, +// parent: schema +// }); +// } +// field.count += 1; +// _.each(value, function(val, key) { +// onFieldSampled(field, key, val); +// }); +// } diff --git a/lib/schema.js b/lib/schema.js index 730691a..e79b1de 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -1,7 +1,6 @@ var es = require('event-stream'); var _ = require('lodash'); var State = require('ampersand-state'); -var parser = require('./parser'); var FieldCollection = require('./field-collection'); /** @@ -9,6 +8,7 @@ var FieldCollection = require('./field-collection'); * @class */ var Schema = State.extend({ + className: 'Schema', idAttribute: 'ns', props: { ns: { @@ -26,11 +26,11 @@ var Schema = State.extend({ var schema = this; schema.count += 1; _.each(doc, function(val, key) { - parser.parse(schema, key, val); - }); - schema.fields.map(function(field) { - field.commit(); + schema.fields.addToField(key, val); }); + // schema.fields.map(function(field) { + // field.commit(); + // }); if (_.isFunction(done)) { done(); } diff --git a/lib/type-collection.js b/lib/type-collection.js index 606d3a4..dfd26b3 100644 --- a/lib/type-collection.js +++ b/lib/type-collection.js @@ -1,20 +1,57 @@ var Collection = require('ampersand-collection'); var lodashMixin = require('ampersand-collection-lodash-mixin'); -var type = require('./type'); var assert = require('assert'); +var _ = require('lodash'); +var debug = require('debug')('mongodb-schema:type-collection'); + +var getTypeName = function (value) { + var T; + if (_.has(value, '_bsontype')) { + T = value._bsontype; + } else { + T = Object.prototype.toString.call(value).replace(/\[object (\w+)\]/, '$1'); + } + // don't want to create naming conflict with javascript Object + if (T === 'Object') T = 'Document'; + return T; +}; module.exports = Collection.extend(lodashMixin, { + className: 'TypeCollection', mainIndex: 'name', - model: function(attrs, options) { - var Klass = type[attrs.name]; - assert(Klass, 'No value type for ' + attrs.name); - return new Klass(attrs, options); - }, /** * Sort by probability descending, with Undefined always last. */ comparator: function(model) { if (model.getId() === 'Undefined') return 0; return model.probability * -1; + }, + model: function(attrs, options) { + // require ./type at runtime to avoid circular imports, does this work with browserify?? + var Klass = require('./type')[attrs.name]; + assert(Klass, 'No value type for ' + attrs.name); + return new Klass(attrs, options); + }, + isModel: function(model) { + // require ./type at runtime to avoid circular imports, does this work with browserify?? + return (model instanceof require('./type').Type); + }, + /** + * adds a new value to the correct type, and creates the type first + * if it doesn't exist yet. + * + * @param {Any} value value to be added + */ + addToType: function(value) { + var typeName = getTypeName(value); + // get or create type + var type = this.get(typeName); + if (!type) { + type = this.add({ + name: typeName + }); + } + // leave it to type to add the value + type.addValue(value); } }); diff --git a/lib/type.js b/lib/type.js index 2e72514..900a478 100644 --- a/lib/type.js +++ b/lib/type.js @@ -1,8 +1,16 @@ var State = require('ampersand-state'); var _ = require('lodash'); var ValueCollection = require('./value-collection'); +var FieldCollection = require('./field-collection'); +var TypeCollection = require('./type-collection'); +var debug = require('debug')('mongodb-schema:type'); +var assert = require('assert'); +var format = require('util').format; -var Type = State.extend({ +/** + * Generic Type superclass has name, count, probability properties + */ +var Type = exports.Type = State.extend({ idAttribute: 'name', props: { name: { @@ -15,7 +23,63 @@ var Type = State.extend({ probability: { type: 'number', default: 0 - }, + } + }, + derived: { + fn: function () { + return this.name; + } + }, + addValue: function() { + this.count += 1; + } +}); + + +/** + * Constant types are just generic types with the appropriate name. + * They do not store any values. + */ +var ConstantType = exports.ConstantType = Type.extend({}); + +exports.Null = ConstantType.extend({ + props: { + name: { + default: 'Null' + } + } +}); + +exports.Undefined = ConstantType.extend({ + props: { + name: { + default: 'Undefined' + } + } +}); + +exports.MaxKey = ConstantType.extend({ + props: { + name: { + default: 'MaxKey' + } + } +}); + +exports.MinKey = ConstantType.extend({ + props: { + name: { + default: 'MinKey' + } + } +}); + + +/** + * Primitive types store their values and have a .unique counter + */ +var PrimitiveType = exports.PrimitiveType = Type.extend({ + props: { unique: { type: 'number', default: 0 @@ -23,20 +87,18 @@ var Type = State.extend({ }, collections: { values: ValueCollection + }, + /** + * adds the value to the value collection. Just passing it through. + * @param {Any} value value to be added + */ + addValue: function (value) { + this.values.add({value: value}); + this.count += 1; } }); -exports.getNameFromValue = function(value) { - var T; - if (_.has(value, '_bsontype')) { - T = value._bsontype; - } else { - T = Object.prototype.toString.call(value).replace(/\[object (\w+)\]/, '$1'); - } - return T; -}; - -exports.String = Type.extend({ +exports.String = PrimitiveType.extend({ props: { name: { default: 'String' @@ -44,7 +106,7 @@ exports.String = Type.extend({ } }); -exports.Number = Type.extend({ +exports.Number = PrimitiveType.extend({ props: { name: { default: 'Number' @@ -52,23 +114,23 @@ exports.Number = Type.extend({ } }); -exports.Long = Type.extend({ +exports.Double = PrimitiveType.extend({ props: { name: { - default: 'Long' + default: 'Double' } } }); -exports.Null = Type.extend({ +exports.Long = PrimitiveType.extend({ props: { name: { - default: 'Null' + default: 'Long' } } }); -exports.Timestamp = Type.extend({ +exports.Timestamp = PrimitiveType.extend({ props: { name: { default: 'Timestamp' @@ -76,7 +138,7 @@ exports.Timestamp = Type.extend({ } }); -exports.Boolean = Type.extend({ +exports.Boolean = PrimitiveType.extend({ props: { name: { default: 'Boolean' @@ -84,7 +146,7 @@ exports.Boolean = Type.extend({ } }); -exports.Date = Type.extend({ +exports.Date = PrimitiveType.extend({ props: { name: { default: 'Date' @@ -92,7 +154,7 @@ exports.Date = Type.extend({ } }); -exports.ObjectID = Type.extend({ +exports.ObjectID = PrimitiveType.extend({ props: { name: { default: 'ObjectID' @@ -100,52 +162,110 @@ exports.ObjectID = Type.extend({ } }); -exports.Undefined = Type.extend({ +exports.Binary = PrimitiveType.extend({ props: { name: { - default: 'Undefined' + default: 'Binary' } } }); -exports.Binary = Type.extend({ +exports.RegExp = PrimitiveType.extend({ props: { name: { - default: 'Binary' + default: 'RegExp' } } }); -exports.MaxKey = Type.extend({ +exports.Symbol = PrimitiveType.extend({ props: { name: { - default: 'MaxKey' + default: 'Symbol' } } }); -exports.MinKey = Type.extend({ +exports.Code = PrimitiveType.extend({ props: { name: { - default: 'MinKey' + default: 'Code' + } + } +}); + +exports.DBRef = PrimitiveType.extend({ + props: { + name: { + default: 'DBRef' } } }); -exports.Object = Type.extend({ +/** + * Documents have sub-fields stored in .fields + */ +exports.Document = Type.extend({ props: { name: { - type: 'string', - default: 'Object' + default: 'Document' } + }, + collections: { + fields: FieldCollection + }, + /** + * parse sub-document and add each key/value to this.fields + * @param {Object} obj The sub-document to be parsed + */ + addValue: function(obj) { + // parse sub-document and add to this.fields + assert(_.isPlainObject(obj), format('value must be object, got `%s`', obj)); + + _.each(obj, function(val, key) { + this.fields.addToField(key, val); + }.bind(this)); + + this.count += 1; } }); -exports.Array = Type.extend({ + +/** + * Arrays have additional .lengths and .average_length properties + * and group their values in a nested .types collection + */ +module.exports.Array = Type.extend({ props: { name: { - type: 'string', default: 'Array' + }, + lengths: { + type: 'array', + default: function() { + return []; + } + } + }, + derived: { + average_length: { + deps: ['lengths'], + fn: function() { + return _.sum(this.lengths) / this.lengths.length; + } } + }, + addValue: function(arr) { + assert(_.isArray(arr), format('value must be array, got `%s`', arr)); + + _.each(arr, function (val) { + this.types.addToType(val); + }.bind(this)); + + this.count += arr.length; + }, + collections: { + types: TypeCollection } }); + diff --git a/lib/value-collection.js b/lib/value-collection.js index 076d81a..3bf4a25 100644 --- a/lib/value-collection.js +++ b/lib/value-collection.js @@ -3,6 +3,7 @@ var lodashMixin = require('ampersand-collection-lodash-mixin'); var Value = require('./value'); module.exports = Collection.extend(lodashMixin, { + className: 'ValueCollection', mainIndex: 'id', model: Value, serialize: function() { diff --git a/lib/value.js b/lib/value.js index 943ac5e..86927f3 100644 --- a/lib/value.js +++ b/lib/value.js @@ -1,6 +1,7 @@ var State = require('ampersand-state'); module.exports = State.extend({ + className: 'Value', idAttribute: 'id', props: { id: { diff --git a/test/type-collection.test.js b/test/type-collection.test.js new file mode 100644 index 0000000..4482749 --- /dev/null +++ b/test/type-collection.test.js @@ -0,0 +1,71 @@ +var TypeCollection = require('../lib/type-collection'); +var _ = require('lodash'); +var assert = require('assert'); +var debug = require('debug')('mongodb-schema:test:type-collection'); +var bson = require('bson'); + + +describe('TypeCollection', function () { + var types; + beforeEach(function () { + types = new TypeCollection(); + }); + + it('should create types automatically with .addToType', function() { + types.addToType("i'm a string"); + assert.ok(types.get('String')); + assert.equal(types.get('String').count, 1); + }); + + it('should use existing types with .addToType', function() { + types.addToType(2); + types.addToType(3); + + assert.ok(types.get('Number')); + assert.equal(types.get('Number').count, 2); + assert.deepEqual(types.get('Number').values.serialize(), [2, 3]); + }); + + it('should work with any type of primitive value', function() { + types.addToType(1); + types.addToType("str"); + types.addToType(true); + types.addToType(null); + types.addToType(undefined); + types.addToType(new Date(2015, 1, 1)); + types.addToType(/^foo*/i); + types.addToType(new bson.ObjectID()); + types.addToType(new bson.Long()); + types.addToType(new bson.Double()); + types.addToType(new bson.Timestamp()); + types.addToType(new bson.Symbol()); + types.addToType(new bson.Code()); + types.addToType(new bson.MinKey()); + types.addToType(new bson.MaxKey()); + types.addToType(new bson.DBRef()); + types.addToType(new bson.Binary()); + + assert.equal(types.length, 17); + assert.equal(_.unique(types.pluck('name')).length, 17); + }); + + it('should add array values correctly', function () { + types.addToType([1, 2, 3]); + assert.ok(types.get('Array')); + assert.equal(types.get('Array').count, 3); + assert.deepEqual(types.get('Array').types.get('Number').values.serialize(), [1, 2, 3]); + }); + + it('should count array values correctly', function () { + types.addToType([1, 2, 3]); + types.addToType("foo"); + types.addToType([4]); + types.addToType(5); + + assert.ok(types.get('Array')); + assert.equal(types.get('Array').count, 4); + assert.deepEqual(types.get('Array').types.get('Number').values.serialize(), [1, 2, 3, 4]); + assert.deepEqual(types.get('Number').count, 1); + assert.deepEqual(types.get('String').count, 1); + }); +}); diff --git a/test/type.test.js b/test/type.test.js new file mode 100644 index 0000000..4336b11 --- /dev/null +++ b/test/type.test.js @@ -0,0 +1,60 @@ +var type = require('../lib/type'); +var assert = require('assert'); +var debug = require('debug')('mongodb-schema:test:type'); + +describe('Array', function () { + var arr; + beforeEach(function () { + arr = new type.Array(); + }); + it('should be constructable', function () { + assert.ok(arr); + }); + + it('should add values of a single type to the correct type', function () { + arr.addValue([5, 2, 5, 5, 0]); + assert.deepEqual(arr.types.get('Number').values.serialize(), [5, 2, 5, 5, 0]); + }); + + it('should throw if the value is not an array', function () { + assert.throws(function() { + arr.addValue(5); + }); + }); + + it('should add values of a mixed types to the correct types', function () { + arr.addValue([false, "foo", true, "bar"]); + assert.deepEqual(arr.types.get('Boolean').values.serialize(), [false, true]); + assert.deepEqual(arr.types.get('String').values.serialize(), ["foo", "bar"]); + }); +}); + + +describe('Document', function () { + var doc; + beforeEach(function () { + doc = new type.Document(); + }); + it('should be constructable', function () { + assert.ok(doc); + }); + + it('should throw if the value is not an object', function () { + assert.throws(function () { + doc.addValue([1, 2, 3]); + }); + }); + + it('should add fields recursively', function () { + doc.addValue({foo: 1}); + doc.addValue({foo: 2}); + doc.addValue({foo: 3}); + doc.addValue({foo: 'hello', bar: 'good bye'}); + assert.ok(doc.fields.get('foo')); + assert.deepEqual(doc.fields.get('foo').values.serialize(), [1, 2, 3, 'hello']); + assert.deepEqual(doc.fields.get('foo').types.get('Number').values.serialize(), [1, 2, 3]); + assert.deepEqual(doc.fields.get('foo').types.get('String').values.serialize(), ['hello']); + assert.deepEqual(doc.fields.get('bar').types.get('String').values.serialize(), ['good bye']); + }); +}); + diff --git a/test/value-collection.test.js b/test/value-collection.test.js new file mode 100644 index 0000000..b0dc89b --- /dev/null +++ b/test/value-collection.test.js @@ -0,0 +1,22 @@ +var ValueCollection = require('../lib/value-collection'); +var _ = require('lodash'); +var assert = require('assert'); +var debug = require('debug')('mongodb-schema:test:value-collection'); + +describe('ValueCollection', function () { + var collection; + before(function () { + collection = new ValueCollection([ + {value: 0}, + {value: ""}, + {value: null}, + {value: false}, + {value: []}, + {value: {}} + ], {parse: true}); + }) + it('should accept any type of value', function () { + assert.deepEqual(collection.serialize(), [0, '', null, false, [], {}]); + assert.equal(collection.length, 6); + }); +}); From ff91c05ac64faf441b12094502ba8455f527f4d2 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 18:25:33 +1000 Subject: [PATCH 06/42] added parentMixin to collections --- lib/collection-parent-mixin.js | 12 ++++++++++++ lib/field-collection.js | 3 ++- lib/type-collection.js | 3 ++- lib/value-collection.js | 3 ++- 4 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 lib/collection-parent-mixin.js diff --git a/lib/collection-parent-mixin.js b/lib/collection-parent-mixin.js new file mode 100644 index 0000000..d2a712a --- /dev/null +++ b/lib/collection-parent-mixin.js @@ -0,0 +1,12 @@ +var _ = require('lodash'); +var AmpersandCollection = require('ampersand-collection'); + +module.exports = { + set: function (models, options) { + // set model parent to collection's parent + options = _.defaults({ + parent: this.parent + }, options || {}); + return AmpersandCollection.prototype.set.call(this, models, options); + } +}; diff --git a/lib/field-collection.js b/lib/field-collection.js index ed3744d..00404f4 100644 --- a/lib/field-collection.js +++ b/lib/field-collection.js @@ -1,12 +1,13 @@ var Collection = require('ampersand-collection'); var lodashMixin = require('ampersand-collection-lodash-mixin'); +var parentMixin = require('./collection-parent-mixin'); var Field = require('./field'); var debug = require('debug')('mongodb-schema:field-collection'); /** * Container for a list of Fields. */ -var FieldCollection = Collection.extend(lodashMixin, { +var FieldCollection = Collection.extend(lodashMixin, parentMixin, { className: 'FieldCollection', mainIndex: 'name', model: Field, diff --git a/lib/type-collection.js b/lib/type-collection.js index dfd26b3..73d2606 100644 --- a/lib/type-collection.js +++ b/lib/type-collection.js @@ -1,5 +1,6 @@ var Collection = require('ampersand-collection'); var lodashMixin = require('ampersand-collection-lodash-mixin'); +var parentMixin = require('./collection-parent-mixin'); var assert = require('assert'); var _ = require('lodash'); var debug = require('debug')('mongodb-schema:type-collection'); @@ -16,7 +17,7 @@ var getTypeName = function (value) { return T; }; -module.exports = Collection.extend(lodashMixin, { +module.exports = Collection.extend(lodashMixin, parentMixin, { className: 'TypeCollection', mainIndex: 'name', /** diff --git a/lib/value-collection.js b/lib/value-collection.js index 3bf4a25..ea5422e 100644 --- a/lib/value-collection.js +++ b/lib/value-collection.js @@ -1,8 +1,9 @@ var Collection = require('ampersand-collection'); var lodashMixin = require('ampersand-collection-lodash-mixin'); +var parentMixin = require('./collection-parent-mixin'); var Value = require('./value'); -module.exports = Collection.extend(lodashMixin, { +module.exports = Collection.extend(lodashMixin, parentMixin, { className: 'ValueCollection', mainIndex: 'id', model: Value, From e3b40109d097d28abe3f8e596515d066d20195c9 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 18:26:24 +1000 Subject: [PATCH 07/42] verify parent is passed down to values. --- test/type-collection.test.js | 7 +++++++ test/value-collection.test.js | 15 +++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/test/type-collection.test.js b/test/type-collection.test.js index 4482749..e58c2b2 100644 --- a/test/type-collection.test.js +++ b/test/type-collection.test.js @@ -1,4 +1,5 @@ var TypeCollection = require('../lib/type-collection'); +var Field = require('../lib/field'); var _ = require('lodash'); var assert = require('assert'); var debug = require('debug')('mongodb-schema:test:type-collection'); @@ -26,6 +27,12 @@ describe('TypeCollection', function () { assert.deepEqual(types.get('Number').values.serialize(), [2, 3]); }); + it('should pass collection\'s parent down to the values', function () { + var field = new Field({name: 'myfield'}); + field.types.addToType('some string'); + assert.equal(field.types.get('String').parent, field); + }); + it('should work with any type of primitive value', function() { types.addToType(1); types.addToType("str"); diff --git a/test/value-collection.test.js b/test/value-collection.test.js index b0dc89b..6d7949f 100644 --- a/test/value-collection.test.js +++ b/test/value-collection.test.js @@ -1,10 +1,12 @@ var ValueCollection = require('../lib/value-collection'); +var NumberType = require('../lib/type').Number; var _ = require('lodash'); var assert = require('assert'); var debug = require('debug')('mongodb-schema:test:value-collection'); describe('ValueCollection', function () { var collection; + before(function () { collection = new ValueCollection([ {value: 0}, @@ -13,10 +15,19 @@ describe('ValueCollection', function () { {value: false}, {value: []}, {value: {}} - ], {parse: true}); - }) + ]); + }); + it('should accept any type of value', function () { assert.deepEqual(collection.serialize(), [0, '', null, false, [], {}]); assert.equal(collection.length, 6); }); + + it('should pass collection\'s parent down to the values', function () { + var num = new NumberType(null); + num.values.reset([ + {value: 250} + ]); + assert.equal(num.values.at(0).parent, num); + }); }); From fde44033ff46bb356e2e9188d7d0360c1f462073 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 19:13:10 +1000 Subject: [PATCH 08/42] added test for field-collection --- test/field-collection.test.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 test/field-collection.test.js diff --git a/test/field-collection.test.js b/test/field-collection.test.js new file mode 100644 index 0000000..0bd5f69 --- /dev/null +++ b/test/field-collection.test.js @@ -0,0 +1,25 @@ +var Document = require('../lib/type').Document; +var FieldCollection = require('../lib/field-collection'); +var _ = require('lodash'); +var assert = require('assert'); +var debug = require('debug')('mongodb-schema:test:field-collection'); + +describe('FieldCollection', function () { + var collection; + + before(function () { + collection = new FieldCollection(); + }); + + it('should create new field if the field name is not present', function () { + collection.addToField('foo', 1); + assert.ok(collection.get('foo')); + assert.equal(collection.length, 1); + }); + + it('should pass down collection\'s parent to its values', function () { + var doc = new Document(); + doc.addValue({foo: 1, bar: 1}); + assert.equal(doc.fields.get('foo').parent, doc); + }); +}); From d9ad384c884e7551ab6a29dd71624743731e5968 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 19:21:40 +1000 Subject: [PATCH 09/42] renamed addValue to parse, schema = document --- lib/field.js | 8 ++++++-- lib/schema.js | 34 +++++----------------------------- lib/type-collection.js | 2 +- lib/type.js | 8 ++++---- test/field-collection.test.js | 2 +- test/type.test.js | 16 ++++++++-------- 6 files changed, 25 insertions(+), 45 deletions(-) diff --git a/lib/field.js b/lib/field.js index 667cf52..bef1f8a 100644 --- a/lib/field.js +++ b/lib/field.js @@ -87,7 +87,7 @@ module.exports = State.extend({ probability: { deps: ['types.length'], fn: function () { - debug('count', this.count, 'parent', this.parent.className, 'pcount', this.parent.count); + if (!this.parent) return null; return this.count / this.parent.count; } }, @@ -100,7 +100,11 @@ module.exports = State.extend({ deps: ['count', 'probability'], fn: function() { if (this.probability === 1) return this.count; - var parentIsArray = this.collection.parent.type === 'Array'; + + var parentIsArray = false; + if (this.collection && this.collection.parent) { + parentIsArray = this.collection.parent.type === 'Array'; + } if (parentIsArray) { return _.sum(this.types.pluck('count')); } diff --git a/lib/schema.js b/lib/schema.js index e79b1de..ea3c607 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -1,46 +1,22 @@ var es = require('event-stream'); -var _ = require('lodash'); -var State = require('ampersand-state'); -var FieldCollection = require('./field-collection'); +var Document = require('./type').Document; /** - * The top level schema state. - * @class + * The top level schema document */ -var Schema = State.extend({ +var Schema = Document.extend({ className: 'Schema', idAttribute: 'ns', props: { ns: { type: 'string' - }, - count: { - type: 'number', - default: 0 - } - }, - collections: { - fields: FieldCollection - }, - parse: function(doc, done) { - var schema = this; - schema.count += 1; - _.each(doc, function(val, key) { - schema.fields.addToField(key, val); - }); - // schema.fields.map(function(field) { - // field.commit(); - // }); - if (_.isFunction(done)) { - done(); } }, stream: function() { var schema = this; return es.map(function(doc, done) { - schema.parse(doc, function(err) { - done(err, doc); - }); + schema.parse(doc); + done(); }); } }); diff --git a/lib/type-collection.js b/lib/type-collection.js index 73d2606..1ff0b42 100644 --- a/lib/type-collection.js +++ b/lib/type-collection.js @@ -53,6 +53,6 @@ module.exports = Collection.extend(lodashMixin, parentMixin, { }); } // leave it to type to add the value - type.addValue(value); + type.parse(value); } }); diff --git a/lib/type.js b/lib/type.js index 900a478..05b1999 100644 --- a/lib/type.js +++ b/lib/type.js @@ -30,7 +30,7 @@ var Type = exports.Type = State.extend({ return this.name; } }, - addValue: function() { + parse: function() { this.count += 1; } }); @@ -92,7 +92,7 @@ var PrimitiveType = exports.PrimitiveType = Type.extend({ * adds the value to the value collection. Just passing it through. * @param {Any} value value to be added */ - addValue: function (value) { + parse: function (value) { this.values.add({value: value}); this.count += 1; } @@ -218,7 +218,7 @@ exports.Document = Type.extend({ * parse sub-document and add each key/value to this.fields * @param {Object} obj The sub-document to be parsed */ - addValue: function(obj) { + parse: function(obj) { // parse sub-document and add to this.fields assert(_.isPlainObject(obj), format('value must be object, got `%s`', obj)); @@ -255,7 +255,7 @@ module.exports.Array = Type.extend({ } } }, - addValue: function(arr) { + parse: function(arr) { assert(_.isArray(arr), format('value must be array, got `%s`', arr)); _.each(arr, function (val) { diff --git a/test/field-collection.test.js b/test/field-collection.test.js index 0bd5f69..0ac786b 100644 --- a/test/field-collection.test.js +++ b/test/field-collection.test.js @@ -19,7 +19,7 @@ describe('FieldCollection', function () { it('should pass down collection\'s parent to its values', function () { var doc = new Document(); - doc.addValue({foo: 1, bar: 1}); + doc.parse({foo: 1, bar: 1}); assert.equal(doc.fields.get('foo').parent, doc); }); }); diff --git a/test/type.test.js b/test/type.test.js index 4336b11..5f12465 100644 --- a/test/type.test.js +++ b/test/type.test.js @@ -12,18 +12,18 @@ describe('Array', function () { }); it('should add values of a single type to the correct type', function () { - arr.addValue([5, 2, 5, 5, 0]); + arr.parse([5, 2, 5, 5, 0]); assert.deepEqual(arr.types.get('Number').values.serialize(), [5, 2, 5, 5, 0]); }); it('should throw if the value is not an array', function () { assert.throws(function() { - arr.addValue(5); + arr.parse(5); }); }); it('should add values of a mixed types to the correct types', function () { - arr.addValue([false, "foo", true, "bar"]); + arr.parse([false, "foo", true, "bar"]); assert.deepEqual(arr.types.get('Boolean').values.serialize(), [false, true]); assert.deepEqual(arr.types.get('String').values.serialize(), ["foo", "bar"]); }); @@ -41,15 +41,15 @@ describe('Document', function () { it('should throw if the value is not an object', function () { assert.throws(function () { - doc.addValue([1, 2, 3]); + doc.parse([1, 2, 3]); }); }); it('should add fields recursively', function () { - doc.addValue({foo: 1}); - doc.addValue({foo: 2}); - doc.addValue({foo: 3}); - doc.addValue({foo: 'hello', bar: 'good bye'}); + doc.parse({foo: 1}); + doc.parse({foo: 2}); + doc.parse({foo: 3}); + doc.parse({foo: 'hello', bar: 'good bye'}); assert.ok(doc.fields.get('foo')); assert.deepEqual(doc.fields.get('foo').values.serialize(), [1, 2, 3, 'hello']); assert.deepEqual(doc.fields.get('foo').types.get('Number').values.serialize(), [1, 2, 3]); From 12823e303c976b91e108ebcfbb11a4e31cbb1235 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 20:10:31 +1000 Subject: [PATCH 10/42] schema name, parents working, array prob --- lib/field.js | 31 ++++++++++++----------- lib/schema.js | 4 ++- lib/type.js | 22 ++++++++++------ test/array-object-types.test.js | 16 ++++++------ test/schema.test.js | 45 +++++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 32 deletions(-) create mode 100644 test/schema.test.js diff --git a/lib/field.js b/lib/field.js index bef1f8a..0502d3a 100644 --- a/lib/field.js +++ b/lib/field.js @@ -85,7 +85,8 @@ module.exports = State.extend({ } }, probability: { - deps: ['types.length'], + deps: ['count', 'parent.count'], + cache: false, fn: function () { if (!this.parent) return null; return this.count / this.parent.count; @@ -96,21 +97,21 @@ module.exports = State.extend({ * This differs from `#count` as it is the value used to calculate * the probability of this field's children. @see #commit() */ - total: { - deps: ['count', 'probability'], - fn: function() { - if (this.probability === 1) return this.count; + // total: { + // deps: ['count', 'probability'], + // fn: function() { + // if (this.probability === 1) return this.count; - var parentIsArray = false; - if (this.collection && this.collection.parent) { - parentIsArray = this.collection.parent.type === 'Array'; - } - if (parentIsArray) { - return _.sum(this.types.pluck('count')); - } - return (this.count / this.probability); - } - }, + // var parentIsArray = false; + // if (this.collection && this.collection.parent) { + // parentIsArray = this.collection.parent.type === 'Array'; + // } + // if (parentIsArray) { + // return _.sum(this.types.pluck('count')); + // } + // return (this.count / this.probability); + // } + // }, /** * Does this field contain any duplicate values? * @returns {Boolean} diff --git a/lib/schema.js b/lib/schema.js index ea3c607..f4a3346 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -5,11 +5,13 @@ var Document = require('./type').Document; * The top level schema document */ var Schema = Document.extend({ - className: 'Schema', idAttribute: 'ns', props: { ns: { type: 'string' + }, + name: { + default: 'Schema' } }, stream: function() { diff --git a/lib/type.js b/lib/type.js index 05b1999..8f3b2f5 100644 --- a/lib/type.js +++ b/lib/type.js @@ -19,16 +19,22 @@ var Type = exports.Type = State.extend({ count: { type: 'number', default: 0 - }, - probability: { - type: 'number', - default: 0 } }, derived: { - fn: function () { - return this.name; - } + className: { + fn: function () { + return this.name; + } + }, + probability: { + // deps: ['count', 'parent.count'], + cache: false, + fn: function () { + if (!this.parent) return null; + return this.count / this.parent.count; + } + }, }, parse: function() { this.count += 1; @@ -262,7 +268,7 @@ module.exports.Array = Type.extend({ this.types.addToType(val); }.bind(this)); - this.count += arr.length; + this.count += 1; }, collections: { types: TypeCollection diff --git a/test/array-object-types.test.js b/test/array-object-types.test.js index c1a649a..bc1b3c1 100644 --- a/test/array-object-types.test.js +++ b/test/array-object-types.test.js @@ -10,7 +10,7 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { { x: { b: 1 } }, { x: [ "bar", null, false ] }, { x: [ {c: 1, d: 1}, {c: 2 } ] }, - { e: 1 } + // { e: 1 } ]; var schema; @@ -32,10 +32,10 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { x.types.pluck('probability') ); assert.deepEqual(dist, { - 'Array': 3/6, - 'String': 1/6, - 'Object': 1/6, - 'Undefined': 1/6 + 'Array': 3/5, + 'String': 1/5, + 'Document': 1/5, + // 'Undefined': 1/6 }); }); @@ -44,7 +44,7 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { }); it('should have an `.fields` alias for convenience', function() { - assert.deepEqual(x.fields, x.types.get('Object').fields); + assert.deepEqual(x.fields, x.types.get('Document').fields); }); }); @@ -70,7 +70,7 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { 'String': 1/8, 'Null': 1/8, 'Boolean': 1/8, - 'Object': 2/8 + 'Document': 2/8 }); }); @@ -83,7 +83,7 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { }); it('should have a `.fields` alias for convenience', function () { - assert.deepEqual(arr.fields, arr.types.get('Object').fields); + assert.deepEqual(arr.fields, arr.types.get('Document').fields); }); }); diff --git a/test/schema.test.js b/test/schema.test.js new file mode 100644 index 0000000..3529342 --- /dev/null +++ b/test/schema.test.js @@ -0,0 +1,45 @@ +var Schema = require('../lib/schema'); +var assert = require('assert'); +var debug = require('debug')('mongodb-schema:test:schema'); + + +describe('Schema', function () { + var schema; + beforeEach(function () { + schema = new Schema(); + }); + + it('should be constructable', function() { + assert.ok(schema); + }); + + it('should parse a simple document', function () { + schema.parse({foo: 1}); + assert.ok(schema.fields.get('foo')); + assert.equal(schema.count, 1); + }); + + it('should parse a nested document', function () { + schema.parse({foo: {bar: 1}}); + assert.ok(schema.fields.get('foo')); + assert.ok(schema.fields.get('foo').types.get('Document').fields.get('bar')); + assert.equal(schema.count, 1); + assert.equal(schema.fields.get('foo').types.get('Document').count, 1); + }); + + it('should set up the parent tree all the way down', function () { + schema.parse({foo: {bar: [1, 2, 3]}}); + var foo = schema.fields.get('foo'); + assert.equal(foo.parent, schema); + var subdoc = foo.types.get('Document'); + assert.equal(subdoc.parent, foo); + var bar = subdoc.fields.get('bar'); + assert.equal(bar.parent, subdoc); + var arr = bar.types.get('Array'); + assert.equal(arr.parent, bar); + var num = arr.types.get('Number'); + assert.equal(num.parent, arr); + var val = num.values.at(0); + assert.equal(val.parent, num); + }); +}); From c51a3b6fc7c0f779a1572a9af965d148e55af650 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 20:40:08 +1000 Subject: [PATCH 11/42] added "Undefined" handling, total_count --- lib/field.js | 1 - lib/type.js | 31 ++++++++++++++++++++++++++----- test/array-object-types.test.js | 28 ++++++++++++++-------------- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/lib/field.js b/lib/field.js index 0502d3a..8e35596 100644 --- a/lib/field.js +++ b/lib/field.js @@ -86,7 +86,6 @@ module.exports = State.extend({ }, probability: { deps: ['count', 'parent.count'], - cache: false, fn: function () { if (!this.parent) return null; return this.count / this.parent.count; diff --git a/lib/type.js b/lib/type.js index 8f3b2f5..7422354 100644 --- a/lib/type.js +++ b/lib/type.js @@ -32,7 +32,7 @@ var Type = exports.Type = State.extend({ cache: false, fn: function () { if (!this.parent) return null; - return this.count / this.parent.count; + return this.count / (this.parent.total_count || this.parent.count); } }, }, @@ -228,8 +228,10 @@ exports.Document = Type.extend({ // parse sub-document and add to this.fields assert(_.isPlainObject(obj), format('value must be object, got `%s`', obj)); - _.each(obj, function(val, key) { - this.fields.addToField(key, val); + // make sure to handle undefined values too + var union = _.union(_.keys(obj), this.fields.pluck('name')); + _.each(union, function(key) { + this.fields.addToField(key, obj[key]); }.bind(this)); this.count += 1; @@ -254,10 +256,28 @@ module.exports.Array = Type.extend({ } }, derived: { + total_count: { + cache: false, + fn: function() { + return _.sum(this.lengths); + } + }, average_length: { - deps: ['lengths'], + deps: ['count'], + fn: function() { + return this.total_count / this.count; + } + }, + /** + * Convenience alias to access sub-fields. Returns + * null if this Field does not have a 'Document' type. + * @returns {FieldCollection} + */ + fields: { + deps: ['types.length'], fn: function() { - return _.sum(this.lengths) / this.lengths.length; + var objType = this.types.get('Document'); + return objType ? objType.fields : null; } } }, @@ -268,6 +288,7 @@ module.exports.Array = Type.extend({ this.types.addToType(val); }.bind(this)); + this.lengths.push(arr.length); this.count += 1; }, collections: { diff --git a/test/array-object-types.test.js b/test/array-object-types.test.js index bc1b3c1..b53bbfd 100644 --- a/test/array-object-types.test.js +++ b/test/array-object-types.test.js @@ -10,7 +10,7 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { { x: { b: 1 } }, { x: [ "bar", null, false ] }, { x: [ {c: 1, d: 1}, {c: 2 } ] }, - // { e: 1 } + { e: 1 } ]; var schema; @@ -32,10 +32,10 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { x.types.pluck('probability') ); assert.deepEqual(dist, { - 'Array': 3/5, - 'String': 1/5, - 'Document': 1/5, - // 'Undefined': 1/6 + 'Array': 3/6, + 'String': 1/6, + 'Document': 1/6, + 'Undefined': 1/6 }); }); @@ -56,10 +56,18 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { arr = schema.fields.get('x').types.get('Array'); }); - it('should return the lengths of all encountered arrays', function () { + it('should return the lengths of all encountered arrays', function() { assert.deepEqual(arr.lengths, [3, 3, 2]); }); + it('should return the probability of x being an array', function(){ + assert.equal(arr.probability, 3/6); + }); + + it('should return the total count of all containing values', function() { + assert.equal(arr.total_count, 8); + }); + it('should return the type distribution inside an array', function () { var arrDist = _.zipObject( arr.types.pluck('name'), @@ -74,14 +82,6 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { }); }); - it('should return the correct count inside the array', function () { - assert.equal(arr.count, 8); - }); - - it('should contain the basic values inside the array', function () { - assert.deepEqual(arr.values.serialize(), [1, 2, 3, 'foo', null, false]); - }); - it('should have a `.fields` alias for convenience', function () { assert.deepEqual(arr.fields, arr.types.get('Document').fields); }); From 7d00798b8b5695ec8fc61dfc1c7461b6d51aca27 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 23:30:57 +1000 Subject: [PATCH 12/42] undefined, end trigger, probabilities --- lib/collection-parent-mixin.js | 4 +- lib/field-collection.js | 11 ++- lib/field.js | 151 ++---------------------------- lib/parser.js | 84 ----------------- lib/schema.js | 9 +- lib/type-collection.js | 5 + test/basic-embedded-array.test.js | 7 +- test/schema.test.js | 12 +++ test/type-collection.test.js | 6 +- 9 files changed, 51 insertions(+), 238 deletions(-) delete mode 100644 lib/parser.js diff --git a/lib/collection-parent-mixin.js b/lib/collection-parent-mixin.js index d2a712a..3f27465 100644 --- a/lib/collection-parent-mixin.js +++ b/lib/collection-parent-mixin.js @@ -1,9 +1,11 @@ var _ = require('lodash'); var AmpersandCollection = require('ampersand-collection'); +/** + * Collection with this mixin passes its parent down to its values + */ module.exports = { set: function (models, options) { - // set model parent to collection's parent options = _.defaults({ parent: this.parent }, options || {}); diff --git a/lib/field-collection.js b/lib/field-collection.js index 00404f4..a17f128 100644 --- a/lib/field-collection.js +++ b/lib/field-collection.js @@ -36,8 +36,17 @@ var FieldCollection = Collection.extend(lodashMixin, parentMixin, { name: name, parent: this.parent }); + // first time we saw this field. We need to compensate for + // the undefined values we missed so far. + if (this.parent && this.parent.count > 0) { + var undef = field.types.add({name: 'Undefined'}); + undef.count += this.parent.count; + } } - field.count += 1; + // undefined are not counted towards the field's count + if(value !== undefined) field.count += 1; + // but they are counted towards the field's total_count + field.total_count += 1; field.types.addToType(value); } }); diff --git a/lib/field.js b/lib/field.js index 8e35596..320f5c3 100644 --- a/lib/field.js +++ b/lib/field.js @@ -1,4 +1,3 @@ -var _ = require('lodash'); var State = require('ampersand-state'); var TypeCollection = require('./type-collection'); var ValueCollection = require('./value-collection'); @@ -26,12 +25,12 @@ module.exports = State.extend({ default: 0 }, /** - * Probability of this field being set. + * Number of counts of all children types, including Undefined */ - // probability: { - // type: 'number', - // default: 0 - // }, + total_count: { + type: 'number', + default: 0 + }, /** * Number of unique values seen. */ @@ -91,26 +90,6 @@ module.exports = State.extend({ return this.count / this.parent.count; } }, - /** - * The total number of documents we would see if always set. - * This differs from `#count` as it is the value used to calculate - * the probability of this field's children. @see #commit() - */ - // total: { - // deps: ['count', 'probability'], - // fn: function() { - // if (this.probability === 1) return this.count; - - // var parentIsArray = false; - // if (this.collection && this.collection.parent) { - // parentIsArray = this.collection.parent.type === 'Array'; - // } - // if (parentIsArray) { - // return _.sum(this.types.pluck('count')); - // } - // return (this.count / this.probability); - // } - // }, /** * Does this field contain any duplicate values? * @returns {Boolean} @@ -144,129 +123,13 @@ module.exports = State.extend({ */ values: ValueCollection }, - /** - * @constructs Field - */ - initialize: function() { - this.listenTo(this.types, 'add', this.onTypeAdded); - this.listenTo(this.types, 'remove', this.onTypeRemoved); - this.listenTo(this.types, 'reset refresh', this.onTypeReset); - }, - /** - * When new types are added, trigger a change event to recalculate `this.type` - * and add listeners so any operations on `type.values` are reflected on - * `this.values`. - * - * @param {Type} type that's being added. - * @param {TypeCollection} collection the type was added to. - * @param {Object} options - */ - onTypeAdded: function(type) { - /** - * Currently have to manually trigger events on collections so - * derived properties are recalculated at the right time. - * In this case, triggering `change:types.length` will cause - * the `type` property to be recalculated correctly. - */ - this.trigger('change:types.length'); - if (type.values) { - this.listenTo(type.values, 'add', this.onValueAdded); - this.listenTo(type.values, 'remove', this.onValueRemoved); - this.listenTo(type.values, 'reset', this.onValueReset); - } - }, - /** - * @see Schema#onTypeAdded - * - * @param {Type} type being removed. - * @param {TypeCollection} collection it was removed from. - * @param {Object} options - */ - onTypeRemoved: function(type) { - this.trigger('change:types.length'); - if (type.values) { - this.stopListening(type.values, 'add', this.onValueAdded); - this.stopListening(type.values, 'remove', this.onValueRemoved); - this.stopListening(type.values, 'reset', this.onValueReset); - } - }, - onTypeReset: function() { - this.trigger('change:types.length'); - }, - /** - * @param {ValueCollection} collection the value was added to. - * @param {Value} value being added. - * @param {Object} options - */ - onValueAdded: function(value) { - this.values.add(value); - }, - /** - * @param {ValueCollection} collection the value was removed from. - * @param {Value} value being removed. - * @param {Object} options - */ - onValueRemoved: function(value) { - this.values.remove(value); - }, - onValueReset: function() { - this.values.reset(); - }, - /** - * We've finished parsing a new document! Finalize all of the probabilities - * and make sure all of our child collections are nicely sorted. - * If we have any subfields, call `commit()` on each of those as well. - */ - // commit: function() { - // var newprob; - // newprob = this.count / this.parent.count; - // if (newprob !== this.probability) { - // this.probability = newprob; - // } - // var undef = this.types.get('Undefined'); - // if ((this.total - this.count) <= 0) { - // if(undef){ - // debug('removing extraneous Undefined for `%s`', this.getId()); - // this.types.remove({ - // name: 'Undefined' - // }); - // } - // // No undefined types to manage - // } else { - // if (!undef) { - // debug('adding Undefined for `%s`', this.getId()); - // undef = this.types.add({ - // name: 'Undefined', - // unique: 1 - // }); - // } - // undef.count = (this.total - this.count); - // undef.probability = (undef.count - this.count); - // } - // this.types.map(function(type) { - // type.probability = type.count / this.total; - // type.unique = _.unique(type.values.pluck('value')).length; - // }.bind(this)); - // this.unique = _.sum(this.types.pluck('unique')); - // this.types.sort(); - - // if (this.fields.length > 0) { - // this.fields.map(function(field) { - // field.commit(); - // }); - // } - // }, serialize: function() { var res = this.getAttributes({ props: true, derived: true }, true); - if (this.fields.length > 0) { - res.fields = this.fields.serialize(); - } else { - res.values = this.values.serialize(); - res.types = this.types.serialize(); - } + res.values = this.values.serialize(); + res.types = this.types.serialize(); return res; }, }); diff --git a/lib/parser.js b/lib/parser.js deleted file mode 100644 index 360c9a5..0000000 --- a/lib/parser.js +++ /dev/null @@ -1,84 +0,0 @@ -// var _ = require('lodash'); - -// var getTypeName = module.exports.getTypeName = function (value) { -// var T; -// if (_.has(value, '_bsontype')) { -// T = value._bsontype; -// } else { -// T = Object.prototype.toString.call(value).replace(/\[object (\w+)\]/, '$1'); -// } -// // don't want to create naming conflict with javascript Object -// if (T === 'Object') T = 'Document'; -// return T; -// }; - -// var addValueToType = module.exports.addValueToTypes = function (types, value) { -// var typeName = getTypeName(value); -// // get or create type -// var type = types.get(typeName); -// if (!type) { -// type = types.add({ -// name: typeName -// }); -// } -// type.count += 1; -// // leave it to type to add the value -// type.addValue(value); -// }; - -// module.exports.addValueToFields = function(schema, name, value) { -// // get or create field -// var field = schema.fields.get(name); -// if (!field) { -// field = schema.fields.add({ -// name: name, -// parent: schema -// }); -// } -// field.count += 1; - -// addValueToType(field.types, value); -// }; - - -// function onEmbeddedArray(schema, name, typeName, value) { -// var field = schema.fields.get(name); - -// if (!field) { -// field = schema.fields.add({ -// name: name, -// klass: Field.EmbeddedArray, -// parent: schema -// }); -// } - -// field.count += 1; -// field.lengths.push(value.length); -// field.trigger('change:lengths'); -// _.each(value, function(d) { -// var typeName = getTypeName(d); -// if (typeName === 'Object') { -// _.each(d, function(val, key) { -// onBasicField(field, key, getTypeName(val), val); -// }); -// } else { -// onBasicField(field, '__basic__', typeName, d); -// } -// }); -// } - -// function onEmbeddedDocument(schema, name, typeName, value) { -// var field = schema.fields.get(name); - -// if (!field) { -// field = schema.fields.add({ -// name: name, -// klass: Field.EmbeddedDocument, -// parent: schema -// }); -// } -// field.count += 1; -// _.each(value, function(val, key) { -// onFieldSampled(field, key, val); -// }); -// } diff --git a/lib/schema.js b/lib/schema.js index f4a3346..91621ba 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -2,7 +2,8 @@ var es = require('event-stream'); var Document = require('./type').Document; /** - * The top level schema document + * The top level schema document, like a Document type + * but with extra stream interface. */ var Schema = Document.extend({ idAttribute: 'ns', @@ -16,10 +17,14 @@ var Schema = Document.extend({ }, stream: function() { var schema = this; - return es.map(function(doc, done) { + var stream = es.map(function(doc, done) { schema.parse(doc); done(); }); + stream.on('end', function () { + schema.trigger('end', this); + }); + return stream; } }); diff --git a/lib/type-collection.js b/lib/type-collection.js index 1ff0b42..1ed20c9 100644 --- a/lib/type-collection.js +++ b/lib/type-collection.js @@ -5,6 +5,11 @@ var assert = require('assert'); var _ = require('lodash'); var debug = require('debug')('mongodb-schema:type-collection'); +/** + * Helper function to get the type name given a value + * @param {Any} value value to get type for + * @return {String} type name, e.g. Boolean or ObjectID + */ var getTypeName = function (value) { var T; if (_.has(value, '_bsontype')) { diff --git a/test/basic-embedded-array.test.js b/test/basic-embedded-array.test.js index cd16420..c79f3c5 100644 --- a/test/basic-embedded-array.test.js +++ b/test/basic-embedded-array.test.js @@ -23,16 +23,16 @@ describe('basic embedded array', function() { before(function(done) { following = getSchema('following', docs, function() { - following_ids = following.fields.get('following_ids').fields.get('__basic__'); + following_ids = following.fields.get('following_ids').types.get('Array'); done(); }); }); it('should have 2 lengths for following_ids', function() { - assert.deepEqual(following.fields.get('following_ids').lengths, [1, 2]); + assert.deepEqual(following_ids.lengths, [1, 2]); }); it('should have an average length of 1.5 for following_ids', function() { - assert.equal(following.fields.get('following_ids').average_length, 1.5); + assert.equal(following_ids.average_length, 1.5); }); it('should have a sum of probability for following_ids of 1', function() { @@ -52,5 +52,4 @@ describe('basic embedded array', function() { following.toJSON(); }); }); - // @todo: write more tests when not so tired... }); diff --git a/test/schema.test.js b/test/schema.test.js index 3529342..5609dae 100644 --- a/test/schema.test.js +++ b/test/schema.test.js @@ -1,6 +1,8 @@ var Schema = require('../lib/schema'); +var getSchema = require('../lib'); var assert = require('assert'); var debug = require('debug')('mongodb-schema:test:schema'); +var es = require('event-stream'); describe('Schema', function () { @@ -42,4 +44,14 @@ describe('Schema', function () { var val = num.values.at(0); assert.equal(val.parent, num); }); + + it('should trigger an `end` event at the end of parsing a stream', function (done) { + var docs = [{foo: 1}, {bar: 1, foo: 1}]; + var src = es.readArray(docs); + schema.on('end', function () { + done(); + }); + + src.pipe(schema.stream()); + }); }); diff --git a/test/type-collection.test.js b/test/type-collection.test.js index e58c2b2..58a18af 100644 --- a/test/type-collection.test.js +++ b/test/type-collection.test.js @@ -59,7 +59,8 @@ describe('TypeCollection', function () { it('should add array values correctly', function () { types.addToType([1, 2, 3]); assert.ok(types.get('Array')); - assert.equal(types.get('Array').count, 3); + assert.equal(types.get('Array').count, 1); + assert.equal(types.get('Array').types.get('Number').count, 3); assert.deepEqual(types.get('Array').types.get('Number').values.serialize(), [1, 2, 3]); }); @@ -70,7 +71,8 @@ describe('TypeCollection', function () { types.addToType(5); assert.ok(types.get('Array')); - assert.equal(types.get('Array').count, 4); + assert.equal(types.get('Array').count, 2); + assert.equal(types.get('Array').types.get('Number').count, 4); assert.deepEqual(types.get('Array').types.get('Number').values.serialize(), [1, 2, 3, 4]); assert.deepEqual(types.get('Number').count, 1); assert.deepEqual(types.get('String').count, 1); From 93393df7b48b8578e3b2867ecb4ac8583d7c4c0f Mon Sep 17 00:00:00 2001 From: Lucas Hrabovsky Date: Sun, 28 Jun 2015 14:30:16 -0400 Subject: [PATCH 13/42] README cleanup --- README.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ec87c1f..bbb1d70 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,6 @@ -# mongodb-schema +# mongodb-schema [![][npm_img]][npm_url] [![][travis_img]][travis_url] [![][coverage_img]][coverage_url] [![][gitter_img]][gitter_url] -[![build status](https://secure.travis-ci.org/mongodb-js/mongodb-schema.png)](http://travis-ci.org/mongodb-js/mongodb-schema) -[![Coverage Status](https://coveralls.io/repos/mongodb-js/mongodb-schema/badge.svg)](https://coveralls.io/r/mongodb-js/mongodb-schema) -[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mongodb-js/mongodb-js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - -Infer a probabilistic schema for a MongoDB collection. +> Infer a probabilistic schema for a MongoDB collection. ## Example @@ -86,7 +82,6 @@ in a collection to derive the schema of: `mongodb-schema` supports all [BSON types][bson-types]. Checkout [the tests][tests] for more usage examples. - ## Installation ``` @@ -121,3 +116,12 @@ A high-level view of the class interactions is as follows: [schema]: https://github.com/mongodb-js/mongodb-language-model/blob/master/lib/schema.js [field]: https://github.com/mongodb-js/mongodb-language-model/blob/master/lib/field.js [type]: https://github.com/mongodb-js/mongodb-language-model/blob/master/lib/type.js + +[travis_img]: https://secure.travis-ci.org/mongodb-js/mongodb-schema.svg?branch=master +[travis_url]: https://travis-ci.org/mongodb-js/mongodb-schema +[npm_img]: https://img.shields.io/npm/v/mongodb-schema.svg +[npm_url]: https://www.npmjs.org/package/mongodb-schema +[coverage_img]: https://coveralls.io/repos/mongodb-js/mongodb-schema/badge.svg +[coverage_url]: https://coveralls.io/r/mongodb-js/mongodb-schema +[gitter_img]: https://badges.gitter.im/Join%20Chat.svg +[gitter_url]: https://gitter.im/mongodb-js/mongodb-js From 51210970174c1a40c3f76913441108da42462379 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 11:12:29 +1000 Subject: [PATCH 14/42] added tests that need to pass after restructuring. --- test/array_object_types.test.js | 85 +++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 test/array_object_types.test.js diff --git a/test/array_object_types.test.js b/test/array_object_types.test.js new file mode 100644 index 0000000..dc511c1 --- /dev/null +++ b/test/array_object_types.test.js @@ -0,0 +1,85 @@ +var getSchema = require('../'); +var assert = require('assert'); +var _ = require('lodash'); + + +describe('arrays and objects as type (INT-203 restructuring)', function () { + var docs = [ + { x: [1, 2, 3] }, + { x: "foo" }, + { x: { b: 1 } }, + { x: [ "bar", null, false ] }, + { x: [ {c: 1, d: 1}, {c: 2 } ] }, + { e: 1 } + ]; + + var schema; + + before(function (done) { + schema = getSchema('mixed.mess', docs, done); + }); + + describe('Field', function () { + it('have the right type distribution of x', function() { + var dist = _.zipObject( + schema.fields.get('x').types.pluck('name'), + schema.fields.get('x').types.pluck('probability') + ); + assert.deepEqual(dist, { + 'Array': 3/6, + 'String': 1/6, + 'Object': 1/6, + 'Undefined': 1/6 + }); + }); + + it('should contain the basic values of x at Field level', function() { + assert.deepEqual(schema.fields.get('x').values.serialize(), ["foo"]); + }); + + it('should have an `.fields` alias for convenience', function() { + assert.deepEqual(schema.fields.get('x').fields, schema.fields.get('x').types.get('Object').fields); + }); + }); + + + describe('Nested Array', function () { + var arr; + + before(function () { + arr = schema.fields.get('x').types.get('Array'); + }); + + it('should return the lengths of all encountered arrays', function () { + assert.deepEqual(arr.lengths, [3, 3, 2]); + }); + + it('should return the type distribution inside an array', function () { + var arrDist = _.zipObject( + arr.types.pluck('name'), + arr.types.pluck('probability') + ); + assert.deepEqual(arrDist, { + 'Number': 3/8, + 'String': 1/8, + 'Null': 1/8, + 'Boolean': 1/8, + 'Object': 2/8 + }); + }); + + it('should return the correct count inside the array', function () { + assert.equal(arr.count, 8); + }); + + it('should contain the basic values inside the array', function () { + assert.deepEqual(arr.values.serialize(), [1, 2, 3, 'foo', null, false]); + }); + + it('should have a `.fields` alias for convenience', function () { + assert.deepEqual(arr.fields, arr.types.get('Object').fields); + }); + + }); + +}); From 8102be41f638553b48739c4338bbb80672a6911e Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 11:13:30 +1000 Subject: [PATCH 15/42] renamed to use slugcase instead of underscores. --- test/{array_object_types.test.js => array-object-types.test.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{array_object_types.test.js => array-object-types.test.js} (100%) diff --git a/test/array_object_types.test.js b/test/array-object-types.test.js similarity index 100% rename from test/array_object_types.test.js rename to test/array-object-types.test.js From 79c9705fd4cd8c28cbbd8afcd84ef8e891d27bef Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 11:15:11 +1000 Subject: [PATCH 16/42] defined x once for readability. --- test/array_object_types.test.js | 91 +++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 test/array_object_types.test.js diff --git a/test/array_object_types.test.js b/test/array_object_types.test.js new file mode 100644 index 0000000..c1a649a --- /dev/null +++ b/test/array_object_types.test.js @@ -0,0 +1,91 @@ +var getSchema = require('../'); +var assert = require('assert'); +var _ = require('lodash'); + + +describe('arrays and objects as type (INT-203 restructuring)', function () { + var docs = [ + { x: [1, 2, 3] }, + { x: "foo" }, + { x: { b: 1 } }, + { x: [ "bar", null, false ] }, + { x: [ {c: 1, d: 1}, {c: 2 } ] }, + { e: 1 } + ]; + + var schema; + + before(function (done) { + schema = getSchema('mixed.mess', docs, done); + }); + + describe('Field', function () { + var x; + + before(function () { + x = schema.fields.get('x'); + }); + + it('have the right type distribution of x', function() { + var dist = _.zipObject( + x.types.pluck('name'), + x.types.pluck('probability') + ); + assert.deepEqual(dist, { + 'Array': 3/6, + 'String': 1/6, + 'Object': 1/6, + 'Undefined': 1/6 + }); + }); + + it('should contain the basic values of x at Field level', function() { + assert.deepEqual(x.values.serialize(), ["foo"]); + }); + + it('should have an `.fields` alias for convenience', function() { + assert.deepEqual(x.fields, x.types.get('Object').fields); + }); + }); + + + describe('Nested Array', function () { + var arr; + + before(function () { + arr = schema.fields.get('x').types.get('Array'); + }); + + it('should return the lengths of all encountered arrays', function () { + assert.deepEqual(arr.lengths, [3, 3, 2]); + }); + + it('should return the type distribution inside an array', function () { + var arrDist = _.zipObject( + arr.types.pluck('name'), + arr.types.pluck('probability') + ); + assert.deepEqual(arrDist, { + 'Number': 3/8, + 'String': 1/8, + 'Null': 1/8, + 'Boolean': 1/8, + 'Object': 2/8 + }); + }); + + it('should return the correct count inside the array', function () { + assert.equal(arr.count, 8); + }); + + it('should contain the basic values inside the array', function () { + assert.deepEqual(arr.values.serialize(), [1, 2, 3, 'foo', null, false]); + }); + + it('should have a `.fields` alias for convenience', function () { + assert.deepEqual(arr.fields, arr.types.get('Object').fields); + }); + + }); + +}); From 69bcb11af7b80936f8f851acbd482622fe82487b Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 11:16:45 +1000 Subject: [PATCH 17/42] defined x once for readability. --- test/array-object-types.test.js | 14 +++-- test/array_object_types.test.js | 91 --------------------------------- 2 files changed, 10 insertions(+), 95 deletions(-) delete mode 100644 test/array_object_types.test.js diff --git a/test/array-object-types.test.js b/test/array-object-types.test.js index dc511c1..c1a649a 100644 --- a/test/array-object-types.test.js +++ b/test/array-object-types.test.js @@ -20,10 +20,16 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { }); describe('Field', function () { + var x; + + before(function () { + x = schema.fields.get('x'); + }); + it('have the right type distribution of x', function() { var dist = _.zipObject( - schema.fields.get('x').types.pluck('name'), - schema.fields.get('x').types.pluck('probability') + x.types.pluck('name'), + x.types.pluck('probability') ); assert.deepEqual(dist, { 'Array': 3/6, @@ -34,11 +40,11 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { }); it('should contain the basic values of x at Field level', function() { - assert.deepEqual(schema.fields.get('x').values.serialize(), ["foo"]); + assert.deepEqual(x.values.serialize(), ["foo"]); }); it('should have an `.fields` alias for convenience', function() { - assert.deepEqual(schema.fields.get('x').fields, schema.fields.get('x').types.get('Object').fields); + assert.deepEqual(x.fields, x.types.get('Object').fields); }); }); diff --git a/test/array_object_types.test.js b/test/array_object_types.test.js deleted file mode 100644 index c1a649a..0000000 --- a/test/array_object_types.test.js +++ /dev/null @@ -1,91 +0,0 @@ -var getSchema = require('../'); -var assert = require('assert'); -var _ = require('lodash'); - - -describe('arrays and objects as type (INT-203 restructuring)', function () { - var docs = [ - { x: [1, 2, 3] }, - { x: "foo" }, - { x: { b: 1 } }, - { x: [ "bar", null, false ] }, - { x: [ {c: 1, d: 1}, {c: 2 } ] }, - { e: 1 } - ]; - - var schema; - - before(function (done) { - schema = getSchema('mixed.mess', docs, done); - }); - - describe('Field', function () { - var x; - - before(function () { - x = schema.fields.get('x'); - }); - - it('have the right type distribution of x', function() { - var dist = _.zipObject( - x.types.pluck('name'), - x.types.pluck('probability') - ); - assert.deepEqual(dist, { - 'Array': 3/6, - 'String': 1/6, - 'Object': 1/6, - 'Undefined': 1/6 - }); - }); - - it('should contain the basic values of x at Field level', function() { - assert.deepEqual(x.values.serialize(), ["foo"]); - }); - - it('should have an `.fields` alias for convenience', function() { - assert.deepEqual(x.fields, x.types.get('Object').fields); - }); - }); - - - describe('Nested Array', function () { - var arr; - - before(function () { - arr = schema.fields.get('x').types.get('Array'); - }); - - it('should return the lengths of all encountered arrays', function () { - assert.deepEqual(arr.lengths, [3, 3, 2]); - }); - - it('should return the type distribution inside an array', function () { - var arrDist = _.zipObject( - arr.types.pluck('name'), - arr.types.pluck('probability') - ); - assert.deepEqual(arrDist, { - 'Number': 3/8, - 'String': 1/8, - 'Null': 1/8, - 'Boolean': 1/8, - 'Object': 2/8 - }); - }); - - it('should return the correct count inside the array', function () { - assert.equal(arr.count, 8); - }); - - it('should contain the basic values inside the array', function () { - assert.deepEqual(arr.values.serialize(), [1, 2, 3, 'foo', null, false]); - }); - - it('should have a `.fields` alias for convenience', function () { - assert.deepEqual(arr.fields, arr.types.get('Object').fields); - }); - - }); - -}); From 9502ec3d26e0aed8ad59919f66f7a651918790e3 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 17:06:25 +1000 Subject: [PATCH 18/42] intermediate checkin, WIP --- lib/field-collection.js | 26 ++++- lib/field.js | 166 +++++++++++++---------------- lib/parser.js | 146 +++++++++++++------------- lib/schema.js | 10 +- lib/type-collection.js | 49 +++++++-- lib/type.js | 190 +++++++++++++++++++++++++++------- lib/value-collection.js | 1 + lib/value.js | 1 + test/type-collection.test.js | 71 +++++++++++++ test/type.test.js | 60 +++++++++++ test/value-collection.test.js | 22 ++++ 11 files changed, 530 insertions(+), 212 deletions(-) create mode 100644 test/type-collection.test.js create mode 100644 test/type.test.js create mode 100644 test/value-collection.test.js diff --git a/lib/field-collection.js b/lib/field-collection.js index 8ff84fa..ed3744d 100644 --- a/lib/field-collection.js +++ b/lib/field-collection.js @@ -1,11 +1,15 @@ var Collection = require('ampersand-collection'); var lodashMixin = require('ampersand-collection-lodash-mixin'); +var Field = require('./field'); +var debug = require('debug')('mongodb-schema:field-collection'); /** * Container for a list of Fields. */ var FieldCollection = Collection.extend(lodashMixin, { + className: 'FieldCollection', mainIndex: 'name', + model: Field, comparator: function (a, b) { // make sure _id is always at top, even in presence of uppercase fields var aId = a.getId(); @@ -15,8 +19,26 @@ var FieldCollection = Collection.extend(lodashMixin, { // otherwise sort case-insensitively return (aId.toLowerCase() < bId.toLowerCase()) ? -1 : 1; }, - model: function(attrs, options) { - return new attrs.klass(attrs, options); + /** + * adds a new name/value pair to the correct field, and creates the + * field first if it doesn't exist yet. Leave it to field.types to + * add the value. + * + * @param {String} name name of the field + * @param {Any} value value to be added + */ + addToField: function (name, value) { + // get or create field + var field = this.get(name); + if (!field) { + field = this.add({ + name: name, + parent: this.parent + }); + } + field.count += 1; + field.types.addToType(value); } }); + module.exports = FieldCollection; diff --git a/lib/field.js b/lib/field.js index 6b9cfee..667cf52 100644 --- a/lib/field.js +++ b/lib/field.js @@ -2,13 +2,13 @@ var _ = require('lodash'); var State = require('ampersand-state'); var TypeCollection = require('./type-collection'); var ValueCollection = require('./value-collection'); -var FieldCollection = require('./field-collection'); var debug = require('debug')('mongodb-schema:field'); /** * Describes a single field in the schema based on sampled values. */ -var Field = State.extend({ +module.exports = State.extend({ + className: 'Field', idAttribute: 'name', props: { /** @@ -28,10 +28,10 @@ var Field = State.extend({ /** * Probability of this field being set. */ - probability: { - type: 'number', - default: 0 - }, + // probability: { + // type: 'number', + // default: 0 + // }, /** * Number of unique values seen. */ @@ -84,6 +84,13 @@ var Field = State.extend({ return this.types.pluck('name'); } }, + probability: { + deps: ['types.length'], + fn: function () { + debug('count', this.count, 'parent', this.parent.className, 'pcount', this.parent.count); + return this.count / this.parent.count; + } + }, /** * The total number of documents we would see if always set. * This differs from `#count` as it is the value used to calculate @@ -109,6 +116,18 @@ var Field = State.extend({ fn: function() { return this.unique < this.count; } + }, + /** + * Convenience alias to access sub-fields. Returns + * null if this Field does not have a 'Document' type. + * @returns {FieldCollection} + */ + fields: { + deps: ['types.length'], + fn: function() { + var objType = this.types.get('Document'); + return objType ? objType.fields : null; + } } }, collections: { @@ -119,11 +138,7 @@ var Field = State.extend({ /** * A sample of values seen for this field. */ - values: ValueCollection, - /** - * Child fields. - */ - fields: FieldCollection + values: ValueCollection }, /** * @constructs Field @@ -150,9 +165,11 @@ var Field = State.extend({ * the `type` property to be recalculated correctly. */ this.trigger('change:types.length'); - this.listenTo(type.values, 'add', this.onValueAdded); - this.listenTo(type.values, 'remove', this.onValueRemoved); - this.listenTo(type.values, 'reset', this.onValueReset); + if (type.values) { + this.listenTo(type.values, 'add', this.onValueAdded); + this.listenTo(type.values, 'remove', this.onValueRemoved); + this.listenTo(type.values, 'reset', this.onValueReset); + } }, /** * @see Schema#onTypeAdded @@ -163,9 +180,11 @@ var Field = State.extend({ */ onTypeRemoved: function(type) { this.trigger('change:types.length'); - this.stopListening(type.values, 'add', this.onValueAdded); - this.stopListening(type.values, 'remove', this.onValueRemoved); - this.stopListening(type.values, 'reset', this.onValueReset); + if (type.values) { + this.stopListening(type.values, 'add', this.onValueAdded); + this.stopListening(type.values, 'remove', this.onValueRemoved); + this.stopListening(type.values, 'reset', this.onValueReset); + } }, onTypeReset: function() { this.trigger('change:types.length'); @@ -194,45 +213,45 @@ var Field = State.extend({ * and make sure all of our child collections are nicely sorted. * If we have any subfields, call `commit()` on each of those as well. */ - commit: function() { - var newprob; - newprob = this.count / this.parent.count; - if (newprob !== this.probability) { - this.probability = newprob; - } - var undef = this.types.get('Undefined'); - if ((this.total - this.count) <= 0) { - if(undef){ - debug('removing extraneous Undefined for `%s`', this.getId()); - this.types.remove({ - name: 'Undefined' - }); - } - // No undefined types to manage - } else { - if (!undef) { - debug('adding Undefined for `%s`', this.getId()); - undef = this.types.add({ - name: 'Undefined', - unique: 1 - }); - } - undef.count = (this.total - this.count); - undef.probability = (undef.count - this.count); - } - this.types.map(function(type) { - type.probability = type.count / this.total; - type.unique = _.unique(type.values.pluck('value')).length; - }.bind(this)); - this.unique = _.sum(this.types.pluck('unique')); - this.types.sort(); + // commit: function() { + // var newprob; + // newprob = this.count / this.parent.count; + // if (newprob !== this.probability) { + // this.probability = newprob; + // } + // var undef = this.types.get('Undefined'); + // if ((this.total - this.count) <= 0) { + // if(undef){ + // debug('removing extraneous Undefined for `%s`', this.getId()); + // this.types.remove({ + // name: 'Undefined' + // }); + // } + // // No undefined types to manage + // } else { + // if (!undef) { + // debug('adding Undefined for `%s`', this.getId()); + // undef = this.types.add({ + // name: 'Undefined', + // unique: 1 + // }); + // } + // undef.count = (this.total - this.count); + // undef.probability = (undef.count - this.count); + // } + // this.types.map(function(type) { + // type.probability = type.count / this.total; + // type.unique = _.unique(type.values.pluck('value')).length; + // }.bind(this)); + // this.unique = _.sum(this.types.pluck('unique')); + // this.types.sort(); - if (this.fields.length > 0) { - this.fields.map(function(field) { - field.commit(); - }); - } - }, + // if (this.fields.length > 0) { + // this.fields.map(function(field) { + // field.commit(); + // }); + // } + // }, serialize: function() { var res = this.getAttributes({ props: true, @@ -247,42 +266,5 @@ var Field = State.extend({ return res; }, }); -module.exports = Field; -/** - * A basic field has no descendant fields, such as `String`, `ObjectID`, - * `Boolean`, or `Date`. - */ -module.exports.Basic = Field.extend({}); -module.exports.EmbeddedArray = Field.extend({ - props: { - type: { - type: 'string', - default: 'Array' - }, - lengths: { - type: 'array', - default: function() { - return []; - } - } - }, - derived: { - average_length: { - deps: ['lengths'], - fn: function() { - return _.sum(this.lengths) / this.lengths.length; - } - } - } -}); - -module.exports.EmbeddedDocument = Field.extend({ - props: { - type: { - type: 'string', - default: 'Object' - } - } -}); diff --git a/lib/parser.js b/lib/parser.js index 656c10a..360c9a5 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -1,82 +1,84 @@ -var _ = require('lodash'); -var getTypeName = require('./type').getNameFromValue; -var Field = require('./field'); +// var _ = require('lodash'); -function onFieldSampled(schema, name, value) { - var typeName = getTypeName(value); - if (typeName === 'Array') { - onEmbeddedArray(schema, name, typeName, value); - } else if (typeName === 'Object') { - onEmbeddedDocument(schema, name, typeName, value); - } else { - onBasicField(schema, name, typeName, value); - } -} +// var getTypeName = module.exports.getTypeName = function (value) { +// var T; +// if (_.has(value, '_bsontype')) { +// T = value._bsontype; +// } else { +// T = Object.prototype.toString.call(value).replace(/\[object (\w+)\]/, '$1'); +// } +// // don't want to create naming conflict with javascript Object +// if (T === 'Object') T = 'Document'; +// return T; +// }; -function onBasicField(schema, name, typeName, value) { - var field = schema.fields.get(name); - if (!field) { - field = schema.fields.add({ - name: name, - klass: Field.Basic, - parent: schema - }); - } - field.count += 1; +// var addValueToType = module.exports.addValueToTypes = function (types, value) { +// var typeName = getTypeName(value); +// // get or create type +// var type = types.get(typeName); +// if (!type) { +// type = types.add({ +// name: typeName +// }); +// } +// type.count += 1; +// // leave it to type to add the value +// type.addValue(value); +// }; - var type = field.types.get(typeName); - if (!type) { - type = field.types.add({ - name: typeName, - }); - } - type.count += 1; +// module.exports.addValueToFields = function(schema, name, value) { +// // get or create field +// var field = schema.fields.get(name); +// if (!field) { +// field = schema.fields.add({ +// name: name, +// parent: schema +// }); +// } +// field.count += 1; - type.values.add({ - value: value - }); -} +// addValueToType(field.types, value); +// }; -function onEmbeddedArray(schema, name, typeName, value) { - var field = schema.fields.get(name); - if (!field) { - field = schema.fields.add({ - name: name, - klass: Field.EmbeddedArray, - parent: schema - }); - } +// function onEmbeddedArray(schema, name, typeName, value) { +// var field = schema.fields.get(name); - field.count += 1; - field.lengths.push(value.length); - field.trigger('change:lengths'); - _.each(value, function(d) { - var typeName = getTypeName(d); - if (typeName === 'Object') { - _.each(d, function(val, key) { - onBasicField(field, key, getTypeName(val), val); - }); - } else { - onBasicField(field, '__basic__', typeName, d); - } - }); -} +// if (!field) { +// field = schema.fields.add({ +// name: name, +// klass: Field.EmbeddedArray, +// parent: schema +// }); +// } -function onEmbeddedDocument(schema, name, typeName, value) { - var field = schema.fields.get(name); +// field.count += 1; +// field.lengths.push(value.length); +// field.trigger('change:lengths'); +// _.each(value, function(d) { +// var typeName = getTypeName(d); +// if (typeName === 'Object') { +// _.each(d, function(val, key) { +// onBasicField(field, key, getTypeName(val), val); +// }); +// } else { +// onBasicField(field, '__basic__', typeName, d); +// } +// }); +// } - if (!field) { - field = schema.fields.add({ - name: name, - klass: Field.EmbeddedDocument, - parent: schema - }); - } - field.count += 1; - _.each(value, function(val, key) { - onFieldSampled(field, key, val); - }); -} +// function onEmbeddedDocument(schema, name, typeName, value) { +// var field = schema.fields.get(name); -module.exports.parse = onFieldSampled; +// if (!field) { +// field = schema.fields.add({ +// name: name, +// klass: Field.EmbeddedDocument, +// parent: schema +// }); +// } +// field.count += 1; +// _.each(value, function(val, key) { +// onFieldSampled(field, key, val); +// }); +// } diff --git a/lib/schema.js b/lib/schema.js index 730691a..e79b1de 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -1,7 +1,6 @@ var es = require('event-stream'); var _ = require('lodash'); var State = require('ampersand-state'); -var parser = require('./parser'); var FieldCollection = require('./field-collection'); /** @@ -9,6 +8,7 @@ var FieldCollection = require('./field-collection'); * @class */ var Schema = State.extend({ + className: 'Schema', idAttribute: 'ns', props: { ns: { @@ -26,11 +26,11 @@ var Schema = State.extend({ var schema = this; schema.count += 1; _.each(doc, function(val, key) { - parser.parse(schema, key, val); - }); - schema.fields.map(function(field) { - field.commit(); + schema.fields.addToField(key, val); }); + // schema.fields.map(function(field) { + // field.commit(); + // }); if (_.isFunction(done)) { done(); } diff --git a/lib/type-collection.js b/lib/type-collection.js index 606d3a4..dfd26b3 100644 --- a/lib/type-collection.js +++ b/lib/type-collection.js @@ -1,20 +1,57 @@ var Collection = require('ampersand-collection'); var lodashMixin = require('ampersand-collection-lodash-mixin'); -var type = require('./type'); var assert = require('assert'); +var _ = require('lodash'); +var debug = require('debug')('mongodb-schema:type-collection'); + +var getTypeName = function (value) { + var T; + if (_.has(value, '_bsontype')) { + T = value._bsontype; + } else { + T = Object.prototype.toString.call(value).replace(/\[object (\w+)\]/, '$1'); + } + // don't want to create naming conflict with javascript Object + if (T === 'Object') T = 'Document'; + return T; +}; module.exports = Collection.extend(lodashMixin, { + className: 'TypeCollection', mainIndex: 'name', - model: function(attrs, options) { - var Klass = type[attrs.name]; - assert(Klass, 'No value type for ' + attrs.name); - return new Klass(attrs, options); - }, /** * Sort by probability descending, with Undefined always last. */ comparator: function(model) { if (model.getId() === 'Undefined') return 0; return model.probability * -1; + }, + model: function(attrs, options) { + // require ./type at runtime to avoid circular imports, does this work with browserify?? + var Klass = require('./type')[attrs.name]; + assert(Klass, 'No value type for ' + attrs.name); + return new Klass(attrs, options); + }, + isModel: function(model) { + // require ./type at runtime to avoid circular imports, does this work with browserify?? + return (model instanceof require('./type').Type); + }, + /** + * adds a new value to the correct type, and creates the type first + * if it doesn't exist yet. + * + * @param {Any} value value to be added + */ + addToType: function(value) { + var typeName = getTypeName(value); + // get or create type + var type = this.get(typeName); + if (!type) { + type = this.add({ + name: typeName + }); + } + // leave it to type to add the value + type.addValue(value); } }); diff --git a/lib/type.js b/lib/type.js index 2e72514..900a478 100644 --- a/lib/type.js +++ b/lib/type.js @@ -1,8 +1,16 @@ var State = require('ampersand-state'); var _ = require('lodash'); var ValueCollection = require('./value-collection'); +var FieldCollection = require('./field-collection'); +var TypeCollection = require('./type-collection'); +var debug = require('debug')('mongodb-schema:type'); +var assert = require('assert'); +var format = require('util').format; -var Type = State.extend({ +/** + * Generic Type superclass has name, count, probability properties + */ +var Type = exports.Type = State.extend({ idAttribute: 'name', props: { name: { @@ -15,7 +23,63 @@ var Type = State.extend({ probability: { type: 'number', default: 0 - }, + } + }, + derived: { + fn: function () { + return this.name; + } + }, + addValue: function() { + this.count += 1; + } +}); + + +/** + * Constant types are just generic types with the appropriate name. + * They do not store any values. + */ +var ConstantType = exports.ConstantType = Type.extend({}); + +exports.Null = ConstantType.extend({ + props: { + name: { + default: 'Null' + } + } +}); + +exports.Undefined = ConstantType.extend({ + props: { + name: { + default: 'Undefined' + } + } +}); + +exports.MaxKey = ConstantType.extend({ + props: { + name: { + default: 'MaxKey' + } + } +}); + +exports.MinKey = ConstantType.extend({ + props: { + name: { + default: 'MinKey' + } + } +}); + + +/** + * Primitive types store their values and have a .unique counter + */ +var PrimitiveType = exports.PrimitiveType = Type.extend({ + props: { unique: { type: 'number', default: 0 @@ -23,20 +87,18 @@ var Type = State.extend({ }, collections: { values: ValueCollection + }, + /** + * adds the value to the value collection. Just passing it through. + * @param {Any} value value to be added + */ + addValue: function (value) { + this.values.add({value: value}); + this.count += 1; } }); -exports.getNameFromValue = function(value) { - var T; - if (_.has(value, '_bsontype')) { - T = value._bsontype; - } else { - T = Object.prototype.toString.call(value).replace(/\[object (\w+)\]/, '$1'); - } - return T; -}; - -exports.String = Type.extend({ +exports.String = PrimitiveType.extend({ props: { name: { default: 'String' @@ -44,7 +106,7 @@ exports.String = Type.extend({ } }); -exports.Number = Type.extend({ +exports.Number = PrimitiveType.extend({ props: { name: { default: 'Number' @@ -52,23 +114,23 @@ exports.Number = Type.extend({ } }); -exports.Long = Type.extend({ +exports.Double = PrimitiveType.extend({ props: { name: { - default: 'Long' + default: 'Double' } } }); -exports.Null = Type.extend({ +exports.Long = PrimitiveType.extend({ props: { name: { - default: 'Null' + default: 'Long' } } }); -exports.Timestamp = Type.extend({ +exports.Timestamp = PrimitiveType.extend({ props: { name: { default: 'Timestamp' @@ -76,7 +138,7 @@ exports.Timestamp = Type.extend({ } }); -exports.Boolean = Type.extend({ +exports.Boolean = PrimitiveType.extend({ props: { name: { default: 'Boolean' @@ -84,7 +146,7 @@ exports.Boolean = Type.extend({ } }); -exports.Date = Type.extend({ +exports.Date = PrimitiveType.extend({ props: { name: { default: 'Date' @@ -92,7 +154,7 @@ exports.Date = Type.extend({ } }); -exports.ObjectID = Type.extend({ +exports.ObjectID = PrimitiveType.extend({ props: { name: { default: 'ObjectID' @@ -100,52 +162,110 @@ exports.ObjectID = Type.extend({ } }); -exports.Undefined = Type.extend({ +exports.Binary = PrimitiveType.extend({ props: { name: { - default: 'Undefined' + default: 'Binary' } } }); -exports.Binary = Type.extend({ +exports.RegExp = PrimitiveType.extend({ props: { name: { - default: 'Binary' + default: 'RegExp' } } }); -exports.MaxKey = Type.extend({ +exports.Symbol = PrimitiveType.extend({ props: { name: { - default: 'MaxKey' + default: 'Symbol' } } }); -exports.MinKey = Type.extend({ +exports.Code = PrimitiveType.extend({ props: { name: { - default: 'MinKey' + default: 'Code' + } + } +}); + +exports.DBRef = PrimitiveType.extend({ + props: { + name: { + default: 'DBRef' } } }); -exports.Object = Type.extend({ +/** + * Documents have sub-fields stored in .fields + */ +exports.Document = Type.extend({ props: { name: { - type: 'string', - default: 'Object' + default: 'Document' } + }, + collections: { + fields: FieldCollection + }, + /** + * parse sub-document and add each key/value to this.fields + * @param {Object} obj The sub-document to be parsed + */ + addValue: function(obj) { + // parse sub-document and add to this.fields + assert(_.isPlainObject(obj), format('value must be object, got `%s`', obj)); + + _.each(obj, function(val, key) { + this.fields.addToField(key, val); + }.bind(this)); + + this.count += 1; } }); -exports.Array = Type.extend({ + +/** + * Arrays have additional .lengths and .average_length properties + * and group their values in a nested .types collection + */ +module.exports.Array = Type.extend({ props: { name: { - type: 'string', default: 'Array' + }, + lengths: { + type: 'array', + default: function() { + return []; + } + } + }, + derived: { + average_length: { + deps: ['lengths'], + fn: function() { + return _.sum(this.lengths) / this.lengths.length; + } } + }, + addValue: function(arr) { + assert(_.isArray(arr), format('value must be array, got `%s`', arr)); + + _.each(arr, function (val) { + this.types.addToType(val); + }.bind(this)); + + this.count += arr.length; + }, + collections: { + types: TypeCollection } }); + diff --git a/lib/value-collection.js b/lib/value-collection.js index 076d81a..3bf4a25 100644 --- a/lib/value-collection.js +++ b/lib/value-collection.js @@ -3,6 +3,7 @@ var lodashMixin = require('ampersand-collection-lodash-mixin'); var Value = require('./value'); module.exports = Collection.extend(lodashMixin, { + className: 'ValueCollection', mainIndex: 'id', model: Value, serialize: function() { diff --git a/lib/value.js b/lib/value.js index 943ac5e..86927f3 100644 --- a/lib/value.js +++ b/lib/value.js @@ -1,6 +1,7 @@ var State = require('ampersand-state'); module.exports = State.extend({ + className: 'Value', idAttribute: 'id', props: { id: { diff --git a/test/type-collection.test.js b/test/type-collection.test.js new file mode 100644 index 0000000..4482749 --- /dev/null +++ b/test/type-collection.test.js @@ -0,0 +1,71 @@ +var TypeCollection = require('../lib/type-collection'); +var _ = require('lodash'); +var assert = require('assert'); +var debug = require('debug')('mongodb-schema:test:type-collection'); +var bson = require('bson'); + + +describe('TypeCollection', function () { + var types; + beforeEach(function () { + types = new TypeCollection(); + }); + + it('should create types automatically with .addToType', function() { + types.addToType("i'm a string"); + assert.ok(types.get('String')); + assert.equal(types.get('String').count, 1); + }); + + it('should use existing types with .addToType', function() { + types.addToType(2); + types.addToType(3); + + assert.ok(types.get('Number')); + assert.equal(types.get('Number').count, 2); + assert.deepEqual(types.get('Number').values.serialize(), [2, 3]); + }); + + it('should work with any type of primitive value', function() { + types.addToType(1); + types.addToType("str"); + types.addToType(true); + types.addToType(null); + types.addToType(undefined); + types.addToType(new Date(2015, 1, 1)); + types.addToType(/^foo*/i); + types.addToType(new bson.ObjectID()); + types.addToType(new bson.Long()); + types.addToType(new bson.Double()); + types.addToType(new bson.Timestamp()); + types.addToType(new bson.Symbol()); + types.addToType(new bson.Code()); + types.addToType(new bson.MinKey()); + types.addToType(new bson.MaxKey()); + types.addToType(new bson.DBRef()); + types.addToType(new bson.Binary()); + + assert.equal(types.length, 17); + assert.equal(_.unique(types.pluck('name')).length, 17); + }); + + it('should add array values correctly', function () { + types.addToType([1, 2, 3]); + assert.ok(types.get('Array')); + assert.equal(types.get('Array').count, 3); + assert.deepEqual(types.get('Array').types.get('Number').values.serialize(), [1, 2, 3]); + }); + + it('should count array values correctly', function () { + types.addToType([1, 2, 3]); + types.addToType("foo"); + types.addToType([4]); + types.addToType(5); + + assert.ok(types.get('Array')); + assert.equal(types.get('Array').count, 4); + assert.deepEqual(types.get('Array').types.get('Number').values.serialize(), [1, 2, 3, 4]); + assert.deepEqual(types.get('Number').count, 1); + assert.deepEqual(types.get('String').count, 1); + }); +}); diff --git a/test/type.test.js b/test/type.test.js new file mode 100644 index 0000000..4336b11 --- /dev/null +++ b/test/type.test.js @@ -0,0 +1,60 @@ +var type = require('../lib/type'); +var assert = require('assert'); +var debug = require('debug')('mongodb-schema:test:type'); + +describe('Array', function () { + var arr; + beforeEach(function () { + arr = new type.Array(); + }); + it('should be constructable', function () { + assert.ok(arr); + }); + + it('should add values of a single type to the correct type', function () { + arr.addValue([5, 2, 5, 5, 0]); + assert.deepEqual(arr.types.get('Number').values.serialize(), [5, 2, 5, 5, 0]); + }); + + it('should throw if the value is not an array', function () { + assert.throws(function() { + arr.addValue(5); + }); + }); + + it('should add values of a mixed types to the correct types', function () { + arr.addValue([false, "foo", true, "bar"]); + assert.deepEqual(arr.types.get('Boolean').values.serialize(), [false, true]); + assert.deepEqual(arr.types.get('String').values.serialize(), ["foo", "bar"]); + }); +}); + + +describe('Document', function () { + var doc; + beforeEach(function () { + doc = new type.Document(); + }); + it('should be constructable', function () { + assert.ok(doc); + }); + + it('should throw if the value is not an object', function () { + assert.throws(function () { + doc.addValue([1, 2, 3]); + }); + }); + + it('should add fields recursively', function () { + doc.addValue({foo: 1}); + doc.addValue({foo: 2}); + doc.addValue({foo: 3}); + doc.addValue({foo: 'hello', bar: 'good bye'}); + assert.ok(doc.fields.get('foo')); + assert.deepEqual(doc.fields.get('foo').values.serialize(), [1, 2, 3, 'hello']); + assert.deepEqual(doc.fields.get('foo').types.get('Number').values.serialize(), [1, 2, 3]); + assert.deepEqual(doc.fields.get('foo').types.get('String').values.serialize(), ['hello']); + assert.deepEqual(doc.fields.get('bar').types.get('String').values.serialize(), ['good bye']); + }); +}); + diff --git a/test/value-collection.test.js b/test/value-collection.test.js new file mode 100644 index 0000000..b0dc89b --- /dev/null +++ b/test/value-collection.test.js @@ -0,0 +1,22 @@ +var ValueCollection = require('../lib/value-collection'); +var _ = require('lodash'); +var assert = require('assert'); +var debug = require('debug')('mongodb-schema:test:value-collection'); + +describe('ValueCollection', function () { + var collection; + before(function () { + collection = new ValueCollection([ + {value: 0}, + {value: ""}, + {value: null}, + {value: false}, + {value: []}, + {value: {}} + ], {parse: true}); + }) + it('should accept any type of value', function () { + assert.deepEqual(collection.serialize(), [0, '', null, false, [], {}]); + assert.equal(collection.length, 6); + }); +}); From 5efe24e36bc546077a86e518fd4800fafc6e040b Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 18:25:33 +1000 Subject: [PATCH 19/42] added parentMixin to collections --- lib/collection-parent-mixin.js | 12 ++++++++++++ lib/field-collection.js | 3 ++- lib/type-collection.js | 3 ++- lib/value-collection.js | 3 ++- 4 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 lib/collection-parent-mixin.js diff --git a/lib/collection-parent-mixin.js b/lib/collection-parent-mixin.js new file mode 100644 index 0000000..d2a712a --- /dev/null +++ b/lib/collection-parent-mixin.js @@ -0,0 +1,12 @@ +var _ = require('lodash'); +var AmpersandCollection = require('ampersand-collection'); + +module.exports = { + set: function (models, options) { + // set model parent to collection's parent + options = _.defaults({ + parent: this.parent + }, options || {}); + return AmpersandCollection.prototype.set.call(this, models, options); + } +}; diff --git a/lib/field-collection.js b/lib/field-collection.js index ed3744d..00404f4 100644 --- a/lib/field-collection.js +++ b/lib/field-collection.js @@ -1,12 +1,13 @@ var Collection = require('ampersand-collection'); var lodashMixin = require('ampersand-collection-lodash-mixin'); +var parentMixin = require('./collection-parent-mixin'); var Field = require('./field'); var debug = require('debug')('mongodb-schema:field-collection'); /** * Container for a list of Fields. */ -var FieldCollection = Collection.extend(lodashMixin, { +var FieldCollection = Collection.extend(lodashMixin, parentMixin, { className: 'FieldCollection', mainIndex: 'name', model: Field, diff --git a/lib/type-collection.js b/lib/type-collection.js index dfd26b3..73d2606 100644 --- a/lib/type-collection.js +++ b/lib/type-collection.js @@ -1,5 +1,6 @@ var Collection = require('ampersand-collection'); var lodashMixin = require('ampersand-collection-lodash-mixin'); +var parentMixin = require('./collection-parent-mixin'); var assert = require('assert'); var _ = require('lodash'); var debug = require('debug')('mongodb-schema:type-collection'); @@ -16,7 +17,7 @@ var getTypeName = function (value) { return T; }; -module.exports = Collection.extend(lodashMixin, { +module.exports = Collection.extend(lodashMixin, parentMixin, { className: 'TypeCollection', mainIndex: 'name', /** diff --git a/lib/value-collection.js b/lib/value-collection.js index 3bf4a25..ea5422e 100644 --- a/lib/value-collection.js +++ b/lib/value-collection.js @@ -1,8 +1,9 @@ var Collection = require('ampersand-collection'); var lodashMixin = require('ampersand-collection-lodash-mixin'); +var parentMixin = require('./collection-parent-mixin'); var Value = require('./value'); -module.exports = Collection.extend(lodashMixin, { +module.exports = Collection.extend(lodashMixin, parentMixin, { className: 'ValueCollection', mainIndex: 'id', model: Value, From 8ac3aceac0d0d8e5ad1c29c2c6c42280b1efe885 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 18:26:24 +1000 Subject: [PATCH 20/42] verify parent is passed down to values. --- test/type-collection.test.js | 7 +++++++ test/value-collection.test.js | 15 +++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/test/type-collection.test.js b/test/type-collection.test.js index 4482749..e58c2b2 100644 --- a/test/type-collection.test.js +++ b/test/type-collection.test.js @@ -1,4 +1,5 @@ var TypeCollection = require('../lib/type-collection'); +var Field = require('../lib/field'); var _ = require('lodash'); var assert = require('assert'); var debug = require('debug')('mongodb-schema:test:type-collection'); @@ -26,6 +27,12 @@ describe('TypeCollection', function () { assert.deepEqual(types.get('Number').values.serialize(), [2, 3]); }); + it('should pass collection\'s parent down to the values', function () { + var field = new Field({name: 'myfield'}); + field.types.addToType('some string'); + assert.equal(field.types.get('String').parent, field); + }); + it('should work with any type of primitive value', function() { types.addToType(1); types.addToType("str"); diff --git a/test/value-collection.test.js b/test/value-collection.test.js index b0dc89b..6d7949f 100644 --- a/test/value-collection.test.js +++ b/test/value-collection.test.js @@ -1,10 +1,12 @@ var ValueCollection = require('../lib/value-collection'); +var NumberType = require('../lib/type').Number; var _ = require('lodash'); var assert = require('assert'); var debug = require('debug')('mongodb-schema:test:value-collection'); describe('ValueCollection', function () { var collection; + before(function () { collection = new ValueCollection([ {value: 0}, @@ -13,10 +15,19 @@ describe('ValueCollection', function () { {value: false}, {value: []}, {value: {}} - ], {parse: true}); - }) + ]); + }); + it('should accept any type of value', function () { assert.deepEqual(collection.serialize(), [0, '', null, false, [], {}]); assert.equal(collection.length, 6); }); + + it('should pass collection\'s parent down to the values', function () { + var num = new NumberType(null); + num.values.reset([ + {value: 250} + ]); + assert.equal(num.values.at(0).parent, num); + }); }); From 6791d278855a4d658e65bb48262effff90ba7b9f Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 19:13:10 +1000 Subject: [PATCH 21/42] added test for field-collection --- test/field-collection.test.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 test/field-collection.test.js diff --git a/test/field-collection.test.js b/test/field-collection.test.js new file mode 100644 index 0000000..0bd5f69 --- /dev/null +++ b/test/field-collection.test.js @@ -0,0 +1,25 @@ +var Document = require('../lib/type').Document; +var FieldCollection = require('../lib/field-collection'); +var _ = require('lodash'); +var assert = require('assert'); +var debug = require('debug')('mongodb-schema:test:field-collection'); + +describe('FieldCollection', function () { + var collection; + + before(function () { + collection = new FieldCollection(); + }); + + it('should create new field if the field name is not present', function () { + collection.addToField('foo', 1); + assert.ok(collection.get('foo')); + assert.equal(collection.length, 1); + }); + + it('should pass down collection\'s parent to its values', function () { + var doc = new Document(); + doc.addValue({foo: 1, bar: 1}); + assert.equal(doc.fields.get('foo').parent, doc); + }); +}); From eab57d4d404dfbdad5659c574a9771afdbf1d930 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 19:21:40 +1000 Subject: [PATCH 22/42] renamed addValue to parse, schema = document --- lib/field.js | 8 ++++++-- lib/schema.js | 34 +++++----------------------------- lib/type-collection.js | 2 +- lib/type.js | 8 ++++---- test/field-collection.test.js | 2 +- test/type.test.js | 16 ++++++++-------- 6 files changed, 25 insertions(+), 45 deletions(-) diff --git a/lib/field.js b/lib/field.js index 667cf52..bef1f8a 100644 --- a/lib/field.js +++ b/lib/field.js @@ -87,7 +87,7 @@ module.exports = State.extend({ probability: { deps: ['types.length'], fn: function () { - debug('count', this.count, 'parent', this.parent.className, 'pcount', this.parent.count); + if (!this.parent) return null; return this.count / this.parent.count; } }, @@ -100,7 +100,11 @@ module.exports = State.extend({ deps: ['count', 'probability'], fn: function() { if (this.probability === 1) return this.count; - var parentIsArray = this.collection.parent.type === 'Array'; + + var parentIsArray = false; + if (this.collection && this.collection.parent) { + parentIsArray = this.collection.parent.type === 'Array'; + } if (parentIsArray) { return _.sum(this.types.pluck('count')); } diff --git a/lib/schema.js b/lib/schema.js index e79b1de..ea3c607 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -1,46 +1,22 @@ var es = require('event-stream'); -var _ = require('lodash'); -var State = require('ampersand-state'); -var FieldCollection = require('./field-collection'); +var Document = require('./type').Document; /** - * The top level schema state. - * @class + * The top level schema document */ -var Schema = State.extend({ +var Schema = Document.extend({ className: 'Schema', idAttribute: 'ns', props: { ns: { type: 'string' - }, - count: { - type: 'number', - default: 0 - } - }, - collections: { - fields: FieldCollection - }, - parse: function(doc, done) { - var schema = this; - schema.count += 1; - _.each(doc, function(val, key) { - schema.fields.addToField(key, val); - }); - // schema.fields.map(function(field) { - // field.commit(); - // }); - if (_.isFunction(done)) { - done(); } }, stream: function() { var schema = this; return es.map(function(doc, done) { - schema.parse(doc, function(err) { - done(err, doc); - }); + schema.parse(doc); + done(); }); } }); diff --git a/lib/type-collection.js b/lib/type-collection.js index 73d2606..1ff0b42 100644 --- a/lib/type-collection.js +++ b/lib/type-collection.js @@ -53,6 +53,6 @@ module.exports = Collection.extend(lodashMixin, parentMixin, { }); } // leave it to type to add the value - type.addValue(value); + type.parse(value); } }); diff --git a/lib/type.js b/lib/type.js index 900a478..05b1999 100644 --- a/lib/type.js +++ b/lib/type.js @@ -30,7 +30,7 @@ var Type = exports.Type = State.extend({ return this.name; } }, - addValue: function() { + parse: function() { this.count += 1; } }); @@ -92,7 +92,7 @@ var PrimitiveType = exports.PrimitiveType = Type.extend({ * adds the value to the value collection. Just passing it through. * @param {Any} value value to be added */ - addValue: function (value) { + parse: function (value) { this.values.add({value: value}); this.count += 1; } @@ -218,7 +218,7 @@ exports.Document = Type.extend({ * parse sub-document and add each key/value to this.fields * @param {Object} obj The sub-document to be parsed */ - addValue: function(obj) { + parse: function(obj) { // parse sub-document and add to this.fields assert(_.isPlainObject(obj), format('value must be object, got `%s`', obj)); @@ -255,7 +255,7 @@ module.exports.Array = Type.extend({ } } }, - addValue: function(arr) { + parse: function(arr) { assert(_.isArray(arr), format('value must be array, got `%s`', arr)); _.each(arr, function (val) { diff --git a/test/field-collection.test.js b/test/field-collection.test.js index 0bd5f69..0ac786b 100644 --- a/test/field-collection.test.js +++ b/test/field-collection.test.js @@ -19,7 +19,7 @@ describe('FieldCollection', function () { it('should pass down collection\'s parent to its values', function () { var doc = new Document(); - doc.addValue({foo: 1, bar: 1}); + doc.parse({foo: 1, bar: 1}); assert.equal(doc.fields.get('foo').parent, doc); }); }); diff --git a/test/type.test.js b/test/type.test.js index 4336b11..5f12465 100644 --- a/test/type.test.js +++ b/test/type.test.js @@ -12,18 +12,18 @@ describe('Array', function () { }); it('should add values of a single type to the correct type', function () { - arr.addValue([5, 2, 5, 5, 0]); + arr.parse([5, 2, 5, 5, 0]); assert.deepEqual(arr.types.get('Number').values.serialize(), [5, 2, 5, 5, 0]); }); it('should throw if the value is not an array', function () { assert.throws(function() { - arr.addValue(5); + arr.parse(5); }); }); it('should add values of a mixed types to the correct types', function () { - arr.addValue([false, "foo", true, "bar"]); + arr.parse([false, "foo", true, "bar"]); assert.deepEqual(arr.types.get('Boolean').values.serialize(), [false, true]); assert.deepEqual(arr.types.get('String').values.serialize(), ["foo", "bar"]); }); @@ -41,15 +41,15 @@ describe('Document', function () { it('should throw if the value is not an object', function () { assert.throws(function () { - doc.addValue([1, 2, 3]); + doc.parse([1, 2, 3]); }); }); it('should add fields recursively', function () { - doc.addValue({foo: 1}); - doc.addValue({foo: 2}); - doc.addValue({foo: 3}); - doc.addValue({foo: 'hello', bar: 'good bye'}); + doc.parse({foo: 1}); + doc.parse({foo: 2}); + doc.parse({foo: 3}); + doc.parse({foo: 'hello', bar: 'good bye'}); assert.ok(doc.fields.get('foo')); assert.deepEqual(doc.fields.get('foo').values.serialize(), [1, 2, 3, 'hello']); assert.deepEqual(doc.fields.get('foo').types.get('Number').values.serialize(), [1, 2, 3]); From af21952b5b66661be63606ff77a3b0762405e01d Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 20:10:31 +1000 Subject: [PATCH 23/42] schema name, parents working, array prob --- lib/field.js | 31 ++++++++++++----------- lib/schema.js | 4 ++- lib/type.js | 22 ++++++++++------ test/array-object-types.test.js | 16 ++++++------ test/schema.test.js | 45 +++++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 32 deletions(-) create mode 100644 test/schema.test.js diff --git a/lib/field.js b/lib/field.js index bef1f8a..0502d3a 100644 --- a/lib/field.js +++ b/lib/field.js @@ -85,7 +85,8 @@ module.exports = State.extend({ } }, probability: { - deps: ['types.length'], + deps: ['count', 'parent.count'], + cache: false, fn: function () { if (!this.parent) return null; return this.count / this.parent.count; @@ -96,21 +97,21 @@ module.exports = State.extend({ * This differs from `#count` as it is the value used to calculate * the probability of this field's children. @see #commit() */ - total: { - deps: ['count', 'probability'], - fn: function() { - if (this.probability === 1) return this.count; + // total: { + // deps: ['count', 'probability'], + // fn: function() { + // if (this.probability === 1) return this.count; - var parentIsArray = false; - if (this.collection && this.collection.parent) { - parentIsArray = this.collection.parent.type === 'Array'; - } - if (parentIsArray) { - return _.sum(this.types.pluck('count')); - } - return (this.count / this.probability); - } - }, + // var parentIsArray = false; + // if (this.collection && this.collection.parent) { + // parentIsArray = this.collection.parent.type === 'Array'; + // } + // if (parentIsArray) { + // return _.sum(this.types.pluck('count')); + // } + // return (this.count / this.probability); + // } + // }, /** * Does this field contain any duplicate values? * @returns {Boolean} diff --git a/lib/schema.js b/lib/schema.js index ea3c607..f4a3346 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -5,11 +5,13 @@ var Document = require('./type').Document; * The top level schema document */ var Schema = Document.extend({ - className: 'Schema', idAttribute: 'ns', props: { ns: { type: 'string' + }, + name: { + default: 'Schema' } }, stream: function() { diff --git a/lib/type.js b/lib/type.js index 05b1999..8f3b2f5 100644 --- a/lib/type.js +++ b/lib/type.js @@ -19,16 +19,22 @@ var Type = exports.Type = State.extend({ count: { type: 'number', default: 0 - }, - probability: { - type: 'number', - default: 0 } }, derived: { - fn: function () { - return this.name; - } + className: { + fn: function () { + return this.name; + } + }, + probability: { + // deps: ['count', 'parent.count'], + cache: false, + fn: function () { + if (!this.parent) return null; + return this.count / this.parent.count; + } + }, }, parse: function() { this.count += 1; @@ -262,7 +268,7 @@ module.exports.Array = Type.extend({ this.types.addToType(val); }.bind(this)); - this.count += arr.length; + this.count += 1; }, collections: { types: TypeCollection diff --git a/test/array-object-types.test.js b/test/array-object-types.test.js index c1a649a..bc1b3c1 100644 --- a/test/array-object-types.test.js +++ b/test/array-object-types.test.js @@ -10,7 +10,7 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { { x: { b: 1 } }, { x: [ "bar", null, false ] }, { x: [ {c: 1, d: 1}, {c: 2 } ] }, - { e: 1 } + // { e: 1 } ]; var schema; @@ -32,10 +32,10 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { x.types.pluck('probability') ); assert.deepEqual(dist, { - 'Array': 3/6, - 'String': 1/6, - 'Object': 1/6, - 'Undefined': 1/6 + 'Array': 3/5, + 'String': 1/5, + 'Document': 1/5, + // 'Undefined': 1/6 }); }); @@ -44,7 +44,7 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { }); it('should have an `.fields` alias for convenience', function() { - assert.deepEqual(x.fields, x.types.get('Object').fields); + assert.deepEqual(x.fields, x.types.get('Document').fields); }); }); @@ -70,7 +70,7 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { 'String': 1/8, 'Null': 1/8, 'Boolean': 1/8, - 'Object': 2/8 + 'Document': 2/8 }); }); @@ -83,7 +83,7 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { }); it('should have a `.fields` alias for convenience', function () { - assert.deepEqual(arr.fields, arr.types.get('Object').fields); + assert.deepEqual(arr.fields, arr.types.get('Document').fields); }); }); diff --git a/test/schema.test.js b/test/schema.test.js new file mode 100644 index 0000000..3529342 --- /dev/null +++ b/test/schema.test.js @@ -0,0 +1,45 @@ +var Schema = require('../lib/schema'); +var assert = require('assert'); +var debug = require('debug')('mongodb-schema:test:schema'); + + +describe('Schema', function () { + var schema; + beforeEach(function () { + schema = new Schema(); + }); + + it('should be constructable', function() { + assert.ok(schema); + }); + + it('should parse a simple document', function () { + schema.parse({foo: 1}); + assert.ok(schema.fields.get('foo')); + assert.equal(schema.count, 1); + }); + + it('should parse a nested document', function () { + schema.parse({foo: {bar: 1}}); + assert.ok(schema.fields.get('foo')); + assert.ok(schema.fields.get('foo').types.get('Document').fields.get('bar')); + assert.equal(schema.count, 1); + assert.equal(schema.fields.get('foo').types.get('Document').count, 1); + }); + + it('should set up the parent tree all the way down', function () { + schema.parse({foo: {bar: [1, 2, 3]}}); + var foo = schema.fields.get('foo'); + assert.equal(foo.parent, schema); + var subdoc = foo.types.get('Document'); + assert.equal(subdoc.parent, foo); + var bar = subdoc.fields.get('bar'); + assert.equal(bar.parent, subdoc); + var arr = bar.types.get('Array'); + assert.equal(arr.parent, bar); + var num = arr.types.get('Number'); + assert.equal(num.parent, arr); + var val = num.values.at(0); + assert.equal(val.parent, num); + }); +}); From 7438723af3ac19ce631a8060b507ebd1178cf4d9 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 20:40:08 +1000 Subject: [PATCH 24/42] added "Undefined" handling, total_count --- lib/field.js | 1 - lib/type.js | 31 ++++++++++++++++++++++++++----- test/array-object-types.test.js | 28 ++++++++++++++-------------- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/lib/field.js b/lib/field.js index 0502d3a..8e35596 100644 --- a/lib/field.js +++ b/lib/field.js @@ -86,7 +86,6 @@ module.exports = State.extend({ }, probability: { deps: ['count', 'parent.count'], - cache: false, fn: function () { if (!this.parent) return null; return this.count / this.parent.count; diff --git a/lib/type.js b/lib/type.js index 8f3b2f5..7422354 100644 --- a/lib/type.js +++ b/lib/type.js @@ -32,7 +32,7 @@ var Type = exports.Type = State.extend({ cache: false, fn: function () { if (!this.parent) return null; - return this.count / this.parent.count; + return this.count / (this.parent.total_count || this.parent.count); } }, }, @@ -228,8 +228,10 @@ exports.Document = Type.extend({ // parse sub-document and add to this.fields assert(_.isPlainObject(obj), format('value must be object, got `%s`', obj)); - _.each(obj, function(val, key) { - this.fields.addToField(key, val); + // make sure to handle undefined values too + var union = _.union(_.keys(obj), this.fields.pluck('name')); + _.each(union, function(key) { + this.fields.addToField(key, obj[key]); }.bind(this)); this.count += 1; @@ -254,10 +256,28 @@ module.exports.Array = Type.extend({ } }, derived: { + total_count: { + cache: false, + fn: function() { + return _.sum(this.lengths); + } + }, average_length: { - deps: ['lengths'], + deps: ['count'], + fn: function() { + return this.total_count / this.count; + } + }, + /** + * Convenience alias to access sub-fields. Returns + * null if this Field does not have a 'Document' type. + * @returns {FieldCollection} + */ + fields: { + deps: ['types.length'], fn: function() { - return _.sum(this.lengths) / this.lengths.length; + var objType = this.types.get('Document'); + return objType ? objType.fields : null; } } }, @@ -268,6 +288,7 @@ module.exports.Array = Type.extend({ this.types.addToType(val); }.bind(this)); + this.lengths.push(arr.length); this.count += 1; }, collections: { diff --git a/test/array-object-types.test.js b/test/array-object-types.test.js index bc1b3c1..b53bbfd 100644 --- a/test/array-object-types.test.js +++ b/test/array-object-types.test.js @@ -10,7 +10,7 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { { x: { b: 1 } }, { x: [ "bar", null, false ] }, { x: [ {c: 1, d: 1}, {c: 2 } ] }, - // { e: 1 } + { e: 1 } ]; var schema; @@ -32,10 +32,10 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { x.types.pluck('probability') ); assert.deepEqual(dist, { - 'Array': 3/5, - 'String': 1/5, - 'Document': 1/5, - // 'Undefined': 1/6 + 'Array': 3/6, + 'String': 1/6, + 'Document': 1/6, + 'Undefined': 1/6 }); }); @@ -56,10 +56,18 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { arr = schema.fields.get('x').types.get('Array'); }); - it('should return the lengths of all encountered arrays', function () { + it('should return the lengths of all encountered arrays', function() { assert.deepEqual(arr.lengths, [3, 3, 2]); }); + it('should return the probability of x being an array', function(){ + assert.equal(arr.probability, 3/6); + }); + + it('should return the total count of all containing values', function() { + assert.equal(arr.total_count, 8); + }); + it('should return the type distribution inside an array', function () { var arrDist = _.zipObject( arr.types.pluck('name'), @@ -74,14 +82,6 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { }); }); - it('should return the correct count inside the array', function () { - assert.equal(arr.count, 8); - }); - - it('should contain the basic values inside the array', function () { - assert.deepEqual(arr.values.serialize(), [1, 2, 3, 'foo', null, false]); - }); - it('should have a `.fields` alias for convenience', function () { assert.deepEqual(arr.fields, arr.types.get('Document').fields); }); From c99e5510f241a49827240718b50dcbba3ceb3962 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 25 Jun 2015 23:30:57 +1000 Subject: [PATCH 25/42] undefined, end trigger, probabilities --- lib/collection-parent-mixin.js | 4 +- lib/field-collection.js | 11 ++- lib/field.js | 151 ++---------------------------- lib/parser.js | 84 ----------------- lib/schema.js | 9 +- lib/type-collection.js | 5 + test/basic-embedded-array.test.js | 7 +- test/schema.test.js | 12 +++ test/type-collection.test.js | 6 +- 9 files changed, 51 insertions(+), 238 deletions(-) delete mode 100644 lib/parser.js diff --git a/lib/collection-parent-mixin.js b/lib/collection-parent-mixin.js index d2a712a..3f27465 100644 --- a/lib/collection-parent-mixin.js +++ b/lib/collection-parent-mixin.js @@ -1,9 +1,11 @@ var _ = require('lodash'); var AmpersandCollection = require('ampersand-collection'); +/** + * Collection with this mixin passes its parent down to its values + */ module.exports = { set: function (models, options) { - // set model parent to collection's parent options = _.defaults({ parent: this.parent }, options || {}); diff --git a/lib/field-collection.js b/lib/field-collection.js index 00404f4..a17f128 100644 --- a/lib/field-collection.js +++ b/lib/field-collection.js @@ -36,8 +36,17 @@ var FieldCollection = Collection.extend(lodashMixin, parentMixin, { name: name, parent: this.parent }); + // first time we saw this field. We need to compensate for + // the undefined values we missed so far. + if (this.parent && this.parent.count > 0) { + var undef = field.types.add({name: 'Undefined'}); + undef.count += this.parent.count; + } } - field.count += 1; + // undefined are not counted towards the field's count + if(value !== undefined) field.count += 1; + // but they are counted towards the field's total_count + field.total_count += 1; field.types.addToType(value); } }); diff --git a/lib/field.js b/lib/field.js index 8e35596..320f5c3 100644 --- a/lib/field.js +++ b/lib/field.js @@ -1,4 +1,3 @@ -var _ = require('lodash'); var State = require('ampersand-state'); var TypeCollection = require('./type-collection'); var ValueCollection = require('./value-collection'); @@ -26,12 +25,12 @@ module.exports = State.extend({ default: 0 }, /** - * Probability of this field being set. + * Number of counts of all children types, including Undefined */ - // probability: { - // type: 'number', - // default: 0 - // }, + total_count: { + type: 'number', + default: 0 + }, /** * Number of unique values seen. */ @@ -91,26 +90,6 @@ module.exports = State.extend({ return this.count / this.parent.count; } }, - /** - * The total number of documents we would see if always set. - * This differs from `#count` as it is the value used to calculate - * the probability of this field's children. @see #commit() - */ - // total: { - // deps: ['count', 'probability'], - // fn: function() { - // if (this.probability === 1) return this.count; - - // var parentIsArray = false; - // if (this.collection && this.collection.parent) { - // parentIsArray = this.collection.parent.type === 'Array'; - // } - // if (parentIsArray) { - // return _.sum(this.types.pluck('count')); - // } - // return (this.count / this.probability); - // } - // }, /** * Does this field contain any duplicate values? * @returns {Boolean} @@ -144,129 +123,13 @@ module.exports = State.extend({ */ values: ValueCollection }, - /** - * @constructs Field - */ - initialize: function() { - this.listenTo(this.types, 'add', this.onTypeAdded); - this.listenTo(this.types, 'remove', this.onTypeRemoved); - this.listenTo(this.types, 'reset refresh', this.onTypeReset); - }, - /** - * When new types are added, trigger a change event to recalculate `this.type` - * and add listeners so any operations on `type.values` are reflected on - * `this.values`. - * - * @param {Type} type that's being added. - * @param {TypeCollection} collection the type was added to. - * @param {Object} options - */ - onTypeAdded: function(type) { - /** - * Currently have to manually trigger events on collections so - * derived properties are recalculated at the right time. - * In this case, triggering `change:types.length` will cause - * the `type` property to be recalculated correctly. - */ - this.trigger('change:types.length'); - if (type.values) { - this.listenTo(type.values, 'add', this.onValueAdded); - this.listenTo(type.values, 'remove', this.onValueRemoved); - this.listenTo(type.values, 'reset', this.onValueReset); - } - }, - /** - * @see Schema#onTypeAdded - * - * @param {Type} type being removed. - * @param {TypeCollection} collection it was removed from. - * @param {Object} options - */ - onTypeRemoved: function(type) { - this.trigger('change:types.length'); - if (type.values) { - this.stopListening(type.values, 'add', this.onValueAdded); - this.stopListening(type.values, 'remove', this.onValueRemoved); - this.stopListening(type.values, 'reset', this.onValueReset); - } - }, - onTypeReset: function() { - this.trigger('change:types.length'); - }, - /** - * @param {ValueCollection} collection the value was added to. - * @param {Value} value being added. - * @param {Object} options - */ - onValueAdded: function(value) { - this.values.add(value); - }, - /** - * @param {ValueCollection} collection the value was removed from. - * @param {Value} value being removed. - * @param {Object} options - */ - onValueRemoved: function(value) { - this.values.remove(value); - }, - onValueReset: function() { - this.values.reset(); - }, - /** - * We've finished parsing a new document! Finalize all of the probabilities - * and make sure all of our child collections are nicely sorted. - * If we have any subfields, call `commit()` on each of those as well. - */ - // commit: function() { - // var newprob; - // newprob = this.count / this.parent.count; - // if (newprob !== this.probability) { - // this.probability = newprob; - // } - // var undef = this.types.get('Undefined'); - // if ((this.total - this.count) <= 0) { - // if(undef){ - // debug('removing extraneous Undefined for `%s`', this.getId()); - // this.types.remove({ - // name: 'Undefined' - // }); - // } - // // No undefined types to manage - // } else { - // if (!undef) { - // debug('adding Undefined for `%s`', this.getId()); - // undef = this.types.add({ - // name: 'Undefined', - // unique: 1 - // }); - // } - // undef.count = (this.total - this.count); - // undef.probability = (undef.count - this.count); - // } - // this.types.map(function(type) { - // type.probability = type.count / this.total; - // type.unique = _.unique(type.values.pluck('value')).length; - // }.bind(this)); - // this.unique = _.sum(this.types.pluck('unique')); - // this.types.sort(); - - // if (this.fields.length > 0) { - // this.fields.map(function(field) { - // field.commit(); - // }); - // } - // }, serialize: function() { var res = this.getAttributes({ props: true, derived: true }, true); - if (this.fields.length > 0) { - res.fields = this.fields.serialize(); - } else { - res.values = this.values.serialize(); - res.types = this.types.serialize(); - } + res.values = this.values.serialize(); + res.types = this.types.serialize(); return res; }, }); diff --git a/lib/parser.js b/lib/parser.js deleted file mode 100644 index 360c9a5..0000000 --- a/lib/parser.js +++ /dev/null @@ -1,84 +0,0 @@ -// var _ = require('lodash'); - -// var getTypeName = module.exports.getTypeName = function (value) { -// var T; -// if (_.has(value, '_bsontype')) { -// T = value._bsontype; -// } else { -// T = Object.prototype.toString.call(value).replace(/\[object (\w+)\]/, '$1'); -// } -// // don't want to create naming conflict with javascript Object -// if (T === 'Object') T = 'Document'; -// return T; -// }; - -// var addValueToType = module.exports.addValueToTypes = function (types, value) { -// var typeName = getTypeName(value); -// // get or create type -// var type = types.get(typeName); -// if (!type) { -// type = types.add({ -// name: typeName -// }); -// } -// type.count += 1; -// // leave it to type to add the value -// type.addValue(value); -// }; - -// module.exports.addValueToFields = function(schema, name, value) { -// // get or create field -// var field = schema.fields.get(name); -// if (!field) { -// field = schema.fields.add({ -// name: name, -// parent: schema -// }); -// } -// field.count += 1; - -// addValueToType(field.types, value); -// }; - - -// function onEmbeddedArray(schema, name, typeName, value) { -// var field = schema.fields.get(name); - -// if (!field) { -// field = schema.fields.add({ -// name: name, -// klass: Field.EmbeddedArray, -// parent: schema -// }); -// } - -// field.count += 1; -// field.lengths.push(value.length); -// field.trigger('change:lengths'); -// _.each(value, function(d) { -// var typeName = getTypeName(d); -// if (typeName === 'Object') { -// _.each(d, function(val, key) { -// onBasicField(field, key, getTypeName(val), val); -// }); -// } else { -// onBasicField(field, '__basic__', typeName, d); -// } -// }); -// } - -// function onEmbeddedDocument(schema, name, typeName, value) { -// var field = schema.fields.get(name); - -// if (!field) { -// field = schema.fields.add({ -// name: name, -// klass: Field.EmbeddedDocument, -// parent: schema -// }); -// } -// field.count += 1; -// _.each(value, function(val, key) { -// onFieldSampled(field, key, val); -// }); -// } diff --git a/lib/schema.js b/lib/schema.js index f4a3346..91621ba 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -2,7 +2,8 @@ var es = require('event-stream'); var Document = require('./type').Document; /** - * The top level schema document + * The top level schema document, like a Document type + * but with extra stream interface. */ var Schema = Document.extend({ idAttribute: 'ns', @@ -16,10 +17,14 @@ var Schema = Document.extend({ }, stream: function() { var schema = this; - return es.map(function(doc, done) { + var stream = es.map(function(doc, done) { schema.parse(doc); done(); }); + stream.on('end', function () { + schema.trigger('end', this); + }); + return stream; } }); diff --git a/lib/type-collection.js b/lib/type-collection.js index 1ff0b42..1ed20c9 100644 --- a/lib/type-collection.js +++ b/lib/type-collection.js @@ -5,6 +5,11 @@ var assert = require('assert'); var _ = require('lodash'); var debug = require('debug')('mongodb-schema:type-collection'); +/** + * Helper function to get the type name given a value + * @param {Any} value value to get type for + * @return {String} type name, e.g. Boolean or ObjectID + */ var getTypeName = function (value) { var T; if (_.has(value, '_bsontype')) { diff --git a/test/basic-embedded-array.test.js b/test/basic-embedded-array.test.js index cd16420..c79f3c5 100644 --- a/test/basic-embedded-array.test.js +++ b/test/basic-embedded-array.test.js @@ -23,16 +23,16 @@ describe('basic embedded array', function() { before(function(done) { following = getSchema('following', docs, function() { - following_ids = following.fields.get('following_ids').fields.get('__basic__'); + following_ids = following.fields.get('following_ids').types.get('Array'); done(); }); }); it('should have 2 lengths for following_ids', function() { - assert.deepEqual(following.fields.get('following_ids').lengths, [1, 2]); + assert.deepEqual(following_ids.lengths, [1, 2]); }); it('should have an average length of 1.5 for following_ids', function() { - assert.equal(following.fields.get('following_ids').average_length, 1.5); + assert.equal(following_ids.average_length, 1.5); }); it('should have a sum of probability for following_ids of 1', function() { @@ -52,5 +52,4 @@ describe('basic embedded array', function() { following.toJSON(); }); }); - // @todo: write more tests when not so tired... }); diff --git a/test/schema.test.js b/test/schema.test.js index 3529342..5609dae 100644 --- a/test/schema.test.js +++ b/test/schema.test.js @@ -1,6 +1,8 @@ var Schema = require('../lib/schema'); +var getSchema = require('../lib'); var assert = require('assert'); var debug = require('debug')('mongodb-schema:test:schema'); +var es = require('event-stream'); describe('Schema', function () { @@ -42,4 +44,14 @@ describe('Schema', function () { var val = num.values.at(0); assert.equal(val.parent, num); }); + + it('should trigger an `end` event at the end of parsing a stream', function (done) { + var docs = [{foo: 1}, {bar: 1, foo: 1}]; + var src = es.readArray(docs); + schema.on('end', function () { + done(); + }); + + src.pipe(schema.stream()); + }); }); diff --git a/test/type-collection.test.js b/test/type-collection.test.js index e58c2b2..58a18af 100644 --- a/test/type-collection.test.js +++ b/test/type-collection.test.js @@ -59,7 +59,8 @@ describe('TypeCollection', function () { it('should add array values correctly', function () { types.addToType([1, 2, 3]); assert.ok(types.get('Array')); - assert.equal(types.get('Array').count, 3); + assert.equal(types.get('Array').count, 1); + assert.equal(types.get('Array').types.get('Number').count, 3); assert.deepEqual(types.get('Array').types.get('Number').values.serialize(), [1, 2, 3]); }); @@ -70,7 +71,8 @@ describe('TypeCollection', function () { types.addToType(5); assert.ok(types.get('Array')); - assert.equal(types.get('Array').count, 4); + assert.equal(types.get('Array').count, 2); + assert.equal(types.get('Array').types.get('Number').count, 4); assert.deepEqual(types.get('Array').types.get('Number').values.serialize(), [1, 2, 3, 4]); assert.deepEqual(types.get('Number').count, 1); assert.deepEqual(types.get('String').count, 1); From a864bb968a70c9ac672c8c8db818ac0126f9bdbc Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Mon, 29 Jun 2015 12:35:08 +1000 Subject: [PATCH 26/42] className --> namespace --- lib/field-collection.js | 9 +++-- lib/field.js | 9 +---- lib/type-collection.js | 2 +- lib/type.js | 88 ++++++++++++++++++++++++++++++----------- lib/value-collection.js | 2 +- lib/value.js | 2 +- 6 files changed, 77 insertions(+), 35 deletions(-) diff --git a/lib/field-collection.js b/lib/field-collection.js index a17f128..cec405d 100644 --- a/lib/field-collection.js +++ b/lib/field-collection.js @@ -8,7 +8,7 @@ var debug = require('debug')('mongodb-schema:field-collection'); * Container for a list of Fields. */ var FieldCollection = Collection.extend(lodashMixin, parentMixin, { - className: 'FieldCollection', + namespace: 'FieldCollection', mainIndex: 'name', model: Field, comparator: function (a, b) { @@ -36,8 +36,11 @@ var FieldCollection = Collection.extend(lodashMixin, parentMixin, { name: name, parent: this.parent }); - // first time we saw this field. We need to compensate for - // the undefined values we missed so far. + /** + * first time we see this field. We need to compensate for + * the Undefined values we missed so far for this field, + * by setting the count to the parent count. + */ if (this.parent && this.parent.count > 0) { var undef = field.types.add({name: 'Undefined'}); undef.count += this.parent.count; diff --git a/lib/field.js b/lib/field.js index 320f5c3..f1bdfaf 100644 --- a/lib/field.js +++ b/lib/field.js @@ -1,13 +1,12 @@ var State = require('ampersand-state'); var TypeCollection = require('./type-collection'); -var ValueCollection = require('./value-collection'); var debug = require('debug')('mongodb-schema:field'); /** * Describes a single field in the schema based on sampled values. */ module.exports = State.extend({ - className: 'Field', + namespace: 'Field', idAttribute: 'name', props: { /** @@ -117,11 +116,7 @@ module.exports = State.extend({ /** * Types seen for this field. */ - types: TypeCollection, - /** - * A sample of values seen for this field. - */ - values: ValueCollection + types: TypeCollection }, serialize: function() { var res = this.getAttributes({ diff --git a/lib/type-collection.js b/lib/type-collection.js index 1ed20c9..0a5be67 100644 --- a/lib/type-collection.js +++ b/lib/type-collection.js @@ -23,7 +23,7 @@ var getTypeName = function (value) { }; module.exports = Collection.extend(lodashMixin, parentMixin, { - className: 'TypeCollection', + namespace: 'TypeCollection', mainIndex: 'name', /** * Sort by probability descending, with Undefined always last. diff --git a/lib/type.js b/lib/type.js index 7422354..1517298 100644 --- a/lib/type.js +++ b/lib/type.js @@ -21,15 +21,17 @@ var Type = exports.Type = State.extend({ default: 0 } }, + session: { + parent: 'state' + }, derived: { - className: { + namespace: { fn: function () { return this.name; } }, probability: { - // deps: ['count', 'parent.count'], - cache: false, + deps: ['count', 'parent.count'], fn: function () { if (!this.parent) return null; return this.count / (this.parent.total_count || this.parent.count); @@ -43,8 +45,7 @@ var Type = exports.Type = State.extend({ /** - * Constant types are just generic types with the appropriate name. - * They do not store any values. + * Types that do not need to store any values */ var ConstantType = exports.ConstantType = Type.extend({}); @@ -64,6 +65,9 @@ exports.Undefined = ConstantType.extend({ } }); +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/MaxKey.html + */ exports.MaxKey = ConstantType.extend({ props: { name: { @@ -72,6 +76,9 @@ exports.MaxKey = ConstantType.extend({ } }); +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/MinKey.html + */ exports.MinKey = ConstantType.extend({ props: { name: { @@ -104,6 +111,9 @@ var PrimitiveType = exports.PrimitiveType = Type.extend({ } }); + +// --- Native Javascript Types --- + exports.String = PrimitiveType.extend({ props: { name: { @@ -120,70 +130,90 @@ exports.Number = PrimitiveType.extend({ } }); -exports.Double = PrimitiveType.extend({ +exports.Boolean = PrimitiveType.extend({ props: { name: { - default: 'Double' + default: 'Boolean' } } }); -exports.Long = PrimitiveType.extend({ +exports.Date = PrimitiveType.extend({ props: { name: { - default: 'Long' + default: 'Date' } } }); -exports.Timestamp = PrimitiveType.extend({ +exports.RegExp = PrimitiveType.extend({ props: { name: { - default: 'Timestamp' + default: 'RegExp' } } }); -exports.Boolean = PrimitiveType.extend({ +// --- BSON Types --- + +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Double.html + */ +exports.Double = PrimitiveType.extend({ props: { name: { - default: 'Boolean' + default: 'Double' } } }); -exports.Date = PrimitiveType.extend({ +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Long.html + */ +exports.Long = PrimitiveType.extend({ props: { name: { - default: 'Date' + default: 'Long' } } }); -exports.ObjectID = PrimitiveType.extend({ +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Timestamp.html + */ +exports.Timestamp = PrimitiveType.extend({ props: { name: { - default: 'ObjectID' + default: 'Timestamp' } } }); -exports.Binary = PrimitiveType.extend({ +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/ObjectID.html + */ +exports.ObjectID = PrimitiveType.extend({ props: { name: { - default: 'Binary' + default: 'ObjectID' } } }); -exports.RegExp = PrimitiveType.extend({ +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Binary.html + */ +exports.Binary = PrimitiveType.extend({ props: { name: { - default: 'RegExp' + default: 'Binary' } } }); +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Symbol.html + */ exports.Symbol = PrimitiveType.extend({ props: { name: { @@ -192,6 +222,9 @@ exports.Symbol = PrimitiveType.extend({ } }); +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Code.html + */ exports.Code = PrimitiveType.extend({ props: { name: { @@ -200,6 +233,9 @@ exports.Code = PrimitiveType.extend({ } }); +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/DBRef.html + */ exports.DBRef = PrimitiveType.extend({ props: { name: { @@ -228,7 +264,15 @@ exports.Document = Type.extend({ // parse sub-document and add to this.fields assert(_.isPlainObject(obj), format('value must be object, got `%s`', obj)); - // make sure to handle undefined values too + /** + * this is a nice way to handle the Undefined values. It iterates over the union + * of object keys and existing field names, automatically inserting undefined + * for the fields that are not in the current object. + * + * Only caveat is that when a field is created for the first time, we need to + * retrospectively bump up the undefined count. That's taken care of in + * @see FieldCollection#addToField + */ var union = _.union(_.keys(obj), this.fields.pluck('name')); _.each(union, function(key) { this.fields.addToField(key, obj[key]); diff --git a/lib/value-collection.js b/lib/value-collection.js index ea5422e..acf5d71 100644 --- a/lib/value-collection.js +++ b/lib/value-collection.js @@ -4,7 +4,7 @@ var parentMixin = require('./collection-parent-mixin'); var Value = require('./value'); module.exports = Collection.extend(lodashMixin, parentMixin, { - className: 'ValueCollection', + namespace: 'ValueCollection', mainIndex: 'id', model: Value, serialize: function() { diff --git a/lib/value.js b/lib/value.js index 86927f3..8871fd2 100644 --- a/lib/value.js +++ b/lib/value.js @@ -1,7 +1,7 @@ var State = require('ampersand-state'); module.exports = State.extend({ - className: 'Value', + namespace: 'Value', idAttribute: 'id', props: { id: { From 7a176df2125c2109a888d2302bbac489206a0e3c Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Mon, 29 Jun 2015 12:48:02 +1000 Subject: [PATCH 27/42] missed dependency on total_count for Type#probability --- lib/field.js | 3 --- lib/type.js | 3 +-- test/array-object-types.test.js | 4 ---- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/lib/field.js b/lib/field.js index f1bdfaf..d867639 100644 --- a/lib/field.js +++ b/lib/field.js @@ -123,10 +123,7 @@ module.exports = State.extend({ props: true, derived: true }, true); - res.values = this.values.serialize(); res.types = this.types.serialize(); return res; }, }); - - diff --git a/lib/type.js b/lib/type.js index 1517298..9a1ac1e 100644 --- a/lib/type.js +++ b/lib/type.js @@ -31,7 +31,7 @@ var Type = exports.Type = State.extend({ } }, probability: { - deps: ['count', 'parent.count'], + deps: ['count', 'parent.count', 'parent.total_count'], fn: function () { if (!this.parent) return null; return this.count / (this.parent.total_count || this.parent.count); @@ -339,4 +339,3 @@ module.exports.Array = Type.extend({ types: TypeCollection } }); - diff --git a/test/array-object-types.test.js b/test/array-object-types.test.js index b53bbfd..3c98dec 100644 --- a/test/array-object-types.test.js +++ b/test/array-object-types.test.js @@ -39,10 +39,6 @@ describe('arrays and objects as type (INT-203 restructuring)', function () { }); }); - it('should contain the basic values of x at Field level', function() { - assert.deepEqual(x.values.serialize(), ["foo"]); - }); - it('should have an `.fields` alias for convenience', function() { assert.deepEqual(x.fields, x.types.get('Document').fields); }); From d0b88f83e98150d83bd6b558db857f2ec8645d43 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Mon, 29 Jun 2015 13:51:54 +1000 Subject: [PATCH 28/42] unique and has_duplicates --- lib/field.js | 26 ++++++++++++++++---------- lib/type.js | 25 +++++++++++++++++++++---- test/basic-unique.test.js | 29 +++++++++++++++++++++-------- 3 files changed, 58 insertions(+), 22 deletions(-) diff --git a/lib/field.js b/lib/field.js index d867639..8f0bc3c 100644 --- a/lib/field.js +++ b/lib/field.js @@ -1,5 +1,6 @@ var State = require('ampersand-state'); var TypeCollection = require('./type-collection'); +var _ = require('lodash'); var debug = require('debug')('mongodb-schema:field'); /** @@ -30,17 +31,10 @@ module.exports = State.extend({ type: 'number', default: 0 }, - /** - * Number of unique values seen. - */ - unique: { - type: 'number', - default: 0 - }, /** * If using shortened keys to save space, it is expected this be the "real" * name of the field that could be input by the user. For example, - * if `u` is the field's `name`, `username` is the field's title + * if `u` is the field's `name`, `username` is the field's `title` * and is much friendlier for humans. */ title: { @@ -89,14 +83,26 @@ module.exports = State.extend({ return this.count / this.parent.count; } }, + /** + * How many unique values. Not using cached property here + * @see Type#unique. + * @returns {Boolean} + */ + unique: { + cache: false, + fn: function () { + return _.sum(this.types.pluck('unique')); + } + }, /** * Does this field contain any duplicate values? + * Not using cached property here, @see Type#unique. * @returns {Boolean} */ has_duplicates: { - deps: ['unique', 'count'], + cache: false, fn: function() { - return this.unique < this.count; + return this.unique < this.total_count; } }, /** diff --git a/lib/type.js b/lib/type.js index 9a1ac1e..fe12761 100644 --- a/lib/type.js +++ b/lib/type.js @@ -47,7 +47,17 @@ var Type = exports.Type = State.extend({ /** * Types that do not need to store any values */ -var ConstantType = exports.ConstantType = Type.extend({}); +var ConstantType = exports.ConstantType = Type.extend({ + derived: { + unique: { + deps: ['count'], + fn: function () { + // more than 1 constant value means no longer unique + return Math.min(this.count, 1); + } + } + } +}); exports.Null = ConstantType.extend({ props: { @@ -92,10 +102,17 @@ exports.MinKey = ConstantType.extend({ * Primitive types store their values and have a .unique counter */ var PrimitiveType = exports.PrimitiveType = Type.extend({ - props: { + derived: { unique: { - type: 'number', - default: 0 + /** + * we're not using a cache here for performance reasons: listening + * to all add/remove/reset/sync events of PrimitiveType#values and + * recalculating uniqueness after each document is not necessary. + */ + cache: false, + fn: function () { + return _.unique(this.values.pluck('value')).length; + } } }, collections: { diff --git a/test/basic-unique.test.js b/test/basic-unique.test.js index f3d71cf..3456312 100644 --- a/test/basic-unique.test.js +++ b/test/basic-unique.test.js @@ -9,7 +9,12 @@ describe('unique', function() { }, { _id: 2, - registered: true + registered: true, + code: null + }, + { + _id: 3, + code: null } ]; @@ -24,13 +29,13 @@ describe('unique', function() { }); }); - it('should have count of 2 for `_id`', function() { - assert.equal(schema.fields.get('_id').count, 2); + it('should have count of 3 for `_id`', function() { + assert.equal(schema.fields.get('_id').count, 3); }); - it('should have unique of 2 for `_id`', function() { - assert.equal(schema.fields.get('_id').unique, 2); - assert.equal(schema.fields.get('_id').types.get('Number').unique, 2); + it('should have unique of 3 for `_id`', function() { + assert.equal(schema.fields.get('_id').unique, 3); + assert.equal(schema.fields.get('_id').types.get('Number').unique, 3); }); it('should not have duplicates for `_id`', function() { @@ -41,8 +46,16 @@ describe('unique', function() { assert.equal(schema.fields.get('registered').count, 2); }); - it('should have unique of 1 for `registered`', function() { - assert.equal(schema.fields.get('registered').unique, 1); + it('should have unique of 1 for `registered` type Boolean', function() { + assert.equal(schema.fields.get('registered').types.get('Boolean').unique, 1); + }); + + it('should have unique of 2 for `registered` overall', function() { + assert.equal(schema.fields.get('registered').unique, 2); + }); + + it('should have unique of 1 for `code`', function() { + assert.equal(schema.fields.get('code').types.get('Null').unique, 1); }); it('should have duplicates for `registered`', function() { From 6b90632af2084434781382c37b49f3ad52deebb2 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Mon, 29 Jun 2015 14:33:28 +1000 Subject: [PATCH 29/42] schema helper takes stream&array. more tests. --- lib/index.js | 8 +++++--- test/events.test.js | 19 ------------------- test/field.test.js | 33 +++++++++++++++++++++++++++++++++ test/schema.test.js | 37 ++++++++++++++++++++++++++++++++++++- test/type.test.js | 17 ++++++++++++++++- 5 files changed, 90 insertions(+), 24 deletions(-) delete mode 100644 test/events.test.js create mode 100644 test/field.test.js diff --git a/lib/index.js b/lib/index.js index b181b68..18f4b06 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,5 +1,6 @@ var Schema = require('./schema'); var es = require('event-stream'); +var debug = require('debug')('mongodb-schema:lib'); /** * Convenience shortcut for parsing schemas. @@ -14,10 +15,11 @@ module.exports = function(ns, docs, fn) { }); var src; - if(docs.stream){ + if(docs.stream && (typeof docs.stream === 'function')) { src = docs.stream(); - } - else{ + } else if (docs.pipe && (typeof docs.pipe === 'function')) { + src = docs; + } else { src = es.readArray(docs); } diff --git a/test/events.test.js b/test/events.test.js deleted file mode 100644 index 8f31ccc..0000000 --- a/test/events.test.js +++ /dev/null @@ -1,19 +0,0 @@ -var Schema = require('../').Schema; -var assert = require('assert'); - -describe('events', function() { - it('should fire a change:type event', function(done) { - var schema = new Schema(); - schema.fields.on('add', function(field) { - - assert.equal(field.getId(), '_id'); - field.on('change:type', function(field, newType) { - assert.equal(newType, 'Number'); - done(); - }); - }); - schema.parse({ - _id: 1 - }); - }); -}); diff --git a/test/field.test.js b/test/field.test.js new file mode 100644 index 0000000..c390ac8 --- /dev/null +++ b/test/field.test.js @@ -0,0 +1,33 @@ +var Field = require('../lib/field'); +var assert = require('assert'); +var debug = require('debug')('mongodb-schema:test:type'); + +describe('Field', function () { + var field; + beforeEach(function () { + field = new Field(); + }); + + it('should be constructable', function () { + assert.ok(field); + }); + + it('should return single type string for Field#type for one type', function () { + field.types.addToType(16); + field.types.addToType(5); + field.types.addToType(-1); + assert.equal(field.type, 'Number'); + }); + + it('should return array of type strings for Field#type for multiple types', function () { + field.types.addToType(16); + field.types.addToType(5); + field.types.addToType("foo"); + field.types.addToType("bar"); + assert.deepEqual(field.type, ['Number', 'String']); + }); + + it('should return undefined for Field#type if no types present', function () { + assert.equal(field.type, undefined); + }); +}); diff --git a/test/schema.test.js b/test/schema.test.js index 5609dae..c96077c 100644 --- a/test/schema.test.js +++ b/test/schema.test.js @@ -1,5 +1,5 @@ var Schema = require('../lib/schema'); -var getSchema = require('../lib'); +var schemaHelper = require('../lib'); var assert = require('assert'); var debug = require('debug')('mongodb-schema:test:schema'); var es = require('event-stream'); @@ -55,3 +55,38 @@ describe('Schema', function () { src.pipe(schema.stream()); }); }); + +describe('Schema Helper', function() { + it('should be able to handle an array as input', function (done) { + var docs = [{foo: 1}, {bar: 1, foo: 2}]; + var src = es.readArray(docs); + var schema; + schema = schemaHelper('with.stream', src, function () { + assert.ok(schema.fields.get('foo')); + assert.ok(schema.fields.get('bar')); + done(); + }); + }); + + it('should be able to handle a stream as input', function (done) { + var docs = [{foo: 1}, {bar: 1, foo: 2}]; + var schema; + schema = schemaHelper('with.stream', docs, function () { + assert.ok(schema.fields.get('foo')); + assert.ok(schema.fields.get('bar')); + done(); + }); + }); + + it('should be able to handle an object as input that exposes a .stream() method', function (done) { + var docs = [{foo: 1}, {bar: 1, foo: 2}]; + var src = es.readArray(docs); + var obj = {name: 'Container Object', stream: function () { return src; }}; + var schema; + schema = schemaHelper('with.stream', obj, function () { + assert.ok(schema.fields.get('foo')); + assert.ok(schema.fields.get('bar')); + done(); + }); + }); +}); diff --git a/test/type.test.js b/test/type.test.js index 5f12465..51a08ad 100644 --- a/test/type.test.js +++ b/test/type.test.js @@ -11,6 +11,10 @@ describe('Array', function () { assert.ok(arr); }); + it('should return Array as its namespace', function () { + assert.equal(arr.getNamespace(), 'Array'); + }); + it('should add values of a single type to the correct type', function () { arr.parse([5, 2, 5, 5, 0]); assert.deepEqual(arr.types.get('Number').values.serialize(), [5, 2, 5, 5, 0]); @@ -22,6 +26,11 @@ describe('Array', function () { }); }); + it('should return null for Type#fields if it does not have a Document type', function() { + arr.parse([1, 2, 3, "string", false]); + assert.equal(arr.fields, null); + }); + it('should add values of a mixed types to the correct types', function () { arr.parse([false, "foo", true, "bar"]); assert.deepEqual(arr.types.get('Boolean').values.serialize(), [false, true]); @@ -45,6 +54,13 @@ describe('Document', function () { }); }); + it('should return null for Type#fields if it does not have a Document type', function() { + doc.parse({foo: 1}); + doc.parse({foo: 2}); + doc.parse({foo: 3}); + assert.equal(doc.fields.get('foo').fields, null); + }); + it('should add fields recursively', function () { doc.parse({foo: 1}); doc.parse({foo: 2}); @@ -57,4 +73,3 @@ describe('Document', function () { assert.deepEqual(doc.fields.get('bar').types.get('String').values.serialize(), ['good bye']); }); }); - From de46593b2b00dd6502dff313f51cdd5b42ba9c48 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Mon, 29 Jun 2015 14:57:48 +1000 Subject: [PATCH 30/42] 100% coverage, all tests passing. --- lib/type-collection.js | 7 +++++++ test/mixed-type-order.test.js | 8 ++++++-- test/type.test.js | 1 - test/values.test.js | 9 ++++++--- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/type-collection.js b/lib/type-collection.js index 0a5be67..6fb1c9f 100644 --- a/lib/type-collection.js +++ b/lib/type-collection.js @@ -22,11 +22,14 @@ var getTypeName = function (value) { return T; }; + module.exports = Collection.extend(lodashMixin, parentMixin, { namespace: 'TypeCollection', mainIndex: 'name', /** * Sort by probability descending, with Undefined always last. + * Note that the application has to call collection.sort() explicitly; + * it will not be sorted automatically for performance reasons. */ comparator: function(model) { if (model.getId() === 'Undefined') return 0; @@ -59,5 +62,9 @@ module.exports = Collection.extend(lodashMixin, parentMixin, { } // leave it to type to add the value type.parse(value); + }, + serialize: function() { + this.sort(); + return Collection.prototype.serialize.call(this); } }); diff --git a/test/mixed-type-order.test.js b/test/mixed-type-order.test.js index 72a82b2..bc75720 100644 --- a/test/mixed-type-order.test.js +++ b/test/mixed-type-order.test.js @@ -37,8 +37,12 @@ describe('mixed type order', function() { it('should have 3 types for `registered`', function() { assert.equal(schema.fields.get('registered').types.length, 3); }); - it('should return the order of types as ["String", "Number", "Undefined"]', function(done) { - assert.deepEqual(schema.fields.get('registered').types.pluck('name'), ['String', 'Number', 'Undefined']); + it('should return the order of types as ["String", "Number", "Undefined"] when sorted', function(done) { + assert.deepEqual(schema.fields.get('registered').types.sort().pluck('name'), ['String', 'Number', 'Undefined']); done(); }); + it('should sort automatically when serialized', function() { + var types = schema.fields.get('registered').types; + assert.deepEqual(_.pluck(types.serialize(), 'name'), ['String', 'Number', 'Undefined']); + }); }); diff --git a/test/type.test.js b/test/type.test.js index 51a08ad..767324c 100644 --- a/test/type.test.js +++ b/test/type.test.js @@ -67,7 +67,6 @@ describe('Document', function () { doc.parse({foo: 3}); doc.parse({foo: 'hello', bar: 'good bye'}); assert.ok(doc.fields.get('foo')); - assert.deepEqual(doc.fields.get('foo').values.serialize(), [1, 2, 3, 'hello']); assert.deepEqual(doc.fields.get('foo').types.get('Number').values.serialize(), [1, 2, 3]); assert.deepEqual(doc.fields.get('foo').types.get('String').values.serialize(), ['hello']); assert.deepEqual(doc.fields.get('bar').types.get('String').values.serialize(), ['good bye']); diff --git a/test/values.test.js b/test/values.test.js index 0a26c7a..29c35cb 100644 --- a/test/values.test.js +++ b/test/values.test.js @@ -6,9 +6,12 @@ describe('values', function() { var schema = new Schema(); schema.fields.on('add', function(field) { assert.equal(field.getId(), '_id'); - field.values.on('add', function(value) { - assert.equal(value.value, 1); - done(); + field.types.on('add', function(type) { + assert.equal(type.name, 'Number'); + type.values.on('add', function(value) { + assert.equal(value.value, 1); + done(); + }); }); }); schema.parse({ From 0121f08e0947ae70ca52674184c0d56f46f6212e Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Mon, 29 Jun 2015 15:24:25 +1000 Subject: [PATCH 31/42] trigger types.length change event in field. --- lib/field-collection.js | 1 + lib/type-collection.js | 1 + test/field.test.js | 13 +++++++++++++ 3 files changed, 15 insertions(+) diff --git a/lib/field-collection.js b/lib/field-collection.js index cec405d..608e5b0 100644 --- a/lib/field-collection.js +++ b/lib/field-collection.js @@ -36,6 +36,7 @@ var FieldCollection = Collection.extend(lodashMixin, parentMixin, { name: name, parent: this.parent }); + if (this.parent) this.parent.trigger('change:fields.length'); /** * first time we see this field. We need to compensate for * the Undefined values we missed so far for this field, diff --git a/lib/type-collection.js b/lib/type-collection.js index 6fb1c9f..5dc7594 100644 --- a/lib/type-collection.js +++ b/lib/type-collection.js @@ -59,6 +59,7 @@ module.exports = Collection.extend(lodashMixin, parentMixin, { type = this.add({ name: typeName }); + if (this.parent) this.parent.trigger('change:types.length'); } // leave it to type to add the value type.parse(value); diff --git a/test/field.test.js b/test/field.test.js index c390ac8..aee1e67 100644 --- a/test/field.test.js +++ b/test/field.test.js @@ -30,4 +30,17 @@ describe('Field', function () { it('should return undefined for Field#type if no types present', function () { assert.equal(field.type, undefined); }); + + it('should trigger types.length events when adding a new type', function () { + field.types.addToType(15); + assert.equal(field.type, 'Number'); + field.types.addToType("sfo"); + assert.deepEqual(field.type, ['Number', 'String']); + }); + + it('should update .fields alias correctly', function () { + assert.equal(field.fields, null); + field.types.addToType({foo: 1}); + assert.equal(field.fields, field.types.get('Document').fields); + }); }); From d9005e94f945469ac8ab18cfa0caeb5a28c55531 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Mon, 29 Jun 2015 15:51:49 +1000 Subject: [PATCH 32/42] split type into individual files under ./types this is to avoid runtime requires, that browserify would not be able to handle. --- lib/schema.js | 2 +- lib/type-collection.js | 6 +- lib/type.js | 358 ---------------------------------- lib/types/array.js | 62 ++++++ lib/types/constant.js | 54 +++++ lib/types/document.js | 43 ++++ lib/types/index.js | 8 + lib/types/primitive.js | 166 ++++++++++++++++ lib/types/type.js | 36 ++++ test/field-collection.test.js | 2 +- test/type.test.js | 6 +- test/value-collection.test.js | 2 +- 12 files changed, 379 insertions(+), 366 deletions(-) delete mode 100644 lib/type.js create mode 100644 lib/types/array.js create mode 100644 lib/types/constant.js create mode 100644 lib/types/document.js create mode 100644 lib/types/index.js create mode 100644 lib/types/primitive.js create mode 100644 lib/types/type.js diff --git a/lib/schema.js b/lib/schema.js index 91621ba..2d97bbb 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -1,5 +1,5 @@ var es = require('event-stream'); -var Document = require('./type').Document; +var Document = require('./types').Document; /** * The top level schema document, like a Document type diff --git a/lib/type-collection.js b/lib/type-collection.js index 5dc7594..7b4bd21 100644 --- a/lib/type-collection.js +++ b/lib/type-collection.js @@ -3,6 +3,8 @@ var lodashMixin = require('ampersand-collection-lodash-mixin'); var parentMixin = require('./collection-parent-mixin'); var assert = require('assert'); var _ = require('lodash'); +var Type = require('./types/type'); +var types = require('./types'); var debug = require('debug')('mongodb-schema:type-collection'); /** @@ -37,13 +39,13 @@ module.exports = Collection.extend(lodashMixin, parentMixin, { }, model: function(attrs, options) { // require ./type at runtime to avoid circular imports, does this work with browserify?? - var Klass = require('./type')[attrs.name]; + var Klass = types[attrs.name]; assert(Klass, 'No value type for ' + attrs.name); return new Klass(attrs, options); }, isModel: function(model) { // require ./type at runtime to avoid circular imports, does this work with browserify?? - return (model instanceof require('./type').Type); + return (model instanceof Type); }, /** * adds a new value to the correct type, and creates the type first diff --git a/lib/type.js b/lib/type.js deleted file mode 100644 index fe12761..0000000 --- a/lib/type.js +++ /dev/null @@ -1,358 +0,0 @@ -var State = require('ampersand-state'); -var _ = require('lodash'); -var ValueCollection = require('./value-collection'); -var FieldCollection = require('./field-collection'); -var TypeCollection = require('./type-collection'); -var debug = require('debug')('mongodb-schema:type'); -var assert = require('assert'); -var format = require('util').format; - -/** - * Generic Type superclass has name, count, probability properties - */ -var Type = exports.Type = State.extend({ - idAttribute: 'name', - props: { - name: { - type: 'string' - }, - count: { - type: 'number', - default: 0 - } - }, - session: { - parent: 'state' - }, - derived: { - namespace: { - fn: function () { - return this.name; - } - }, - probability: { - deps: ['count', 'parent.count', 'parent.total_count'], - fn: function () { - if (!this.parent) return null; - return this.count / (this.parent.total_count || this.parent.count); - } - }, - }, - parse: function() { - this.count += 1; - } -}); - - -/** - * Types that do not need to store any values - */ -var ConstantType = exports.ConstantType = Type.extend({ - derived: { - unique: { - deps: ['count'], - fn: function () { - // more than 1 constant value means no longer unique - return Math.min(this.count, 1); - } - } - } -}); - -exports.Null = ConstantType.extend({ - props: { - name: { - default: 'Null' - } - } -}); - -exports.Undefined = ConstantType.extend({ - props: { - name: { - default: 'Undefined' - } - } -}); - -/** - * @see http://mongodb.github.io/node-mongodb-native/2.0/api/MaxKey.html - */ -exports.MaxKey = ConstantType.extend({ - props: { - name: { - default: 'MaxKey' - } - } -}); - -/** - * @see http://mongodb.github.io/node-mongodb-native/2.0/api/MinKey.html - */ -exports.MinKey = ConstantType.extend({ - props: { - name: { - default: 'MinKey' - } - } -}); - - -/** - * Primitive types store their values and have a .unique counter - */ -var PrimitiveType = exports.PrimitiveType = Type.extend({ - derived: { - unique: { - /** - * we're not using a cache here for performance reasons: listening - * to all add/remove/reset/sync events of PrimitiveType#values and - * recalculating uniqueness after each document is not necessary. - */ - cache: false, - fn: function () { - return _.unique(this.values.pluck('value')).length; - } - } - }, - collections: { - values: ValueCollection - }, - /** - * adds the value to the value collection. Just passing it through. - * @param {Any} value value to be added - */ - parse: function (value) { - this.values.add({value: value}); - this.count += 1; - } -}); - - -// --- Native Javascript Types --- - -exports.String = PrimitiveType.extend({ - props: { - name: { - default: 'String' - } - } -}); - -exports.Number = PrimitiveType.extend({ - props: { - name: { - default: 'Number' - } - } -}); - -exports.Boolean = PrimitiveType.extend({ - props: { - name: { - default: 'Boolean' - } - } -}); - -exports.Date = PrimitiveType.extend({ - props: { - name: { - default: 'Date' - } - } -}); - -exports.RegExp = PrimitiveType.extend({ - props: { - name: { - default: 'RegExp' - } - } -}); - -// --- BSON Types --- - -/** - * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Double.html - */ -exports.Double = PrimitiveType.extend({ - props: { - name: { - default: 'Double' - } - } -}); - -/** - * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Long.html - */ -exports.Long = PrimitiveType.extend({ - props: { - name: { - default: 'Long' - } - } -}); - -/** - * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Timestamp.html - */ -exports.Timestamp = PrimitiveType.extend({ - props: { - name: { - default: 'Timestamp' - } - } -}); - -/** - * @see http://mongodb.github.io/node-mongodb-native/2.0/api/ObjectID.html - */ -exports.ObjectID = PrimitiveType.extend({ - props: { - name: { - default: 'ObjectID' - } - } -}); - -/** - * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Binary.html - */ -exports.Binary = PrimitiveType.extend({ - props: { - name: { - default: 'Binary' - } - } -}); - -/** - * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Symbol.html - */ -exports.Symbol = PrimitiveType.extend({ - props: { - name: { - default: 'Symbol' - } - } -}); - -/** - * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Code.html - */ -exports.Code = PrimitiveType.extend({ - props: { - name: { - default: 'Code' - } - } -}); - -/** - * @see http://mongodb.github.io/node-mongodb-native/2.0/api/DBRef.html - */ -exports.DBRef = PrimitiveType.extend({ - props: { - name: { - default: 'DBRef' - } - } -}); - -/** - * Documents have sub-fields stored in .fields - */ -exports.Document = Type.extend({ - props: { - name: { - default: 'Document' - } - }, - collections: { - fields: FieldCollection - }, - /** - * parse sub-document and add each key/value to this.fields - * @param {Object} obj The sub-document to be parsed - */ - parse: function(obj) { - // parse sub-document and add to this.fields - assert(_.isPlainObject(obj), format('value must be object, got `%s`', obj)); - - /** - * this is a nice way to handle the Undefined values. It iterates over the union - * of object keys and existing field names, automatically inserting undefined - * for the fields that are not in the current object. - * - * Only caveat is that when a field is created for the first time, we need to - * retrospectively bump up the undefined count. That's taken care of in - * @see FieldCollection#addToField - */ - var union = _.union(_.keys(obj), this.fields.pluck('name')); - _.each(union, function(key) { - this.fields.addToField(key, obj[key]); - }.bind(this)); - - this.count += 1; - } -}); - - -/** - * Arrays have additional .lengths and .average_length properties - * and group their values in a nested .types collection - */ -module.exports.Array = Type.extend({ - props: { - name: { - default: 'Array' - }, - lengths: { - type: 'array', - default: function() { - return []; - } - } - }, - derived: { - total_count: { - cache: false, - fn: function() { - return _.sum(this.lengths); - } - }, - average_length: { - deps: ['count'], - fn: function() { - return this.total_count / this.count; - } - }, - /** - * Convenience alias to access sub-fields. Returns - * null if this Field does not have a 'Document' type. - * @returns {FieldCollection} - */ - fields: { - deps: ['types.length'], - fn: function() { - var objType = this.types.get('Document'); - return objType ? objType.fields : null; - } - } - }, - parse: function(arr) { - assert(_.isArray(arr), format('value must be array, got `%s`', arr)); - - _.each(arr, function (val) { - this.types.addToType(val); - }.bind(this)); - - this.lengths.push(arr.length); - this.count += 1; - }, - collections: { - types: TypeCollection - } -}); diff --git a/lib/types/array.js b/lib/types/array.js new file mode 100644 index 0000000..5a09da3 --- /dev/null +++ b/lib/types/array.js @@ -0,0 +1,62 @@ +var Type = require('./type'); +var _ = require('lodash'); +var format = require('util').format; +var TypeCollection = require('../type-collection'); +var assert = require('assert'); + +/** + * Arrays have additional .lengths and .average_length properties + * and group their values in a nested .types collection + */ +module.exports.Array = Type.extend({ + props: { + name: { + default: 'Array' + }, + lengths: { + type: 'array', + default: function() { + return []; + } + } + }, + derived: { + total_count: { + cache: false, + fn: function() { + return _.sum(this.lengths); + } + }, + average_length: { + deps: ['count'], + fn: function() { + return this.total_count / this.count; + } + }, + /** + * Convenience alias to access sub-fields. Returns + * null if this Field does not have a 'Document' type. + * @returns {FieldCollection} + */ + fields: { + deps: ['types.length'], + fn: function() { + var objType = this.types.get('Document'); + return objType ? objType.fields : null; + } + } + }, + parse: function(arr) { + assert(_.isArray(arr), format('value must be array, got `%s`', arr)); + + _.each(arr, function (val) { + this.types.addToType(val); + }.bind(this)); + + this.lengths.push(arr.length); + this.count += 1; + }, + collections: { + types: TypeCollection + } +}); diff --git a/lib/types/constant.js b/lib/types/constant.js new file mode 100644 index 0000000..90d2858 --- /dev/null +++ b/lib/types/constant.js @@ -0,0 +1,54 @@ +var Type = require('./type'); + +/** + * Types that do not need to store any values + */ +var ConstantType = Type.extend({ + derived: { + unique: { + deps: ['count'], + fn: function () { + // more than 1 constant value means no longer unique + return Math.min(this.count, 1); + } + } + } +}); + +module.exports.Null = ConstantType.extend({ + props: { + name: { + default: 'Null' + } + } +}); + +module.exports.Undefined = ConstantType.extend({ + props: { + name: { + default: 'Undefined' + } + } +}); + +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/MaxKey.html + */ +module.exports.MaxKey = ConstantType.extend({ + props: { + name: { + default: 'MaxKey' + } + } +}); + +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/MinKey.html + */ +module.exports.MinKey = ConstantType.extend({ + props: { + name: { + default: 'MinKey' + } + } +}); diff --git a/lib/types/document.js b/lib/types/document.js new file mode 100644 index 0000000..53ddc73 --- /dev/null +++ b/lib/types/document.js @@ -0,0 +1,43 @@ +var Type = require('./type'); +var FieldCollection = require('../field-collection'); +var assert = require('assert'); +var _ = require('lodash'); +var format = require('util').format; + +/** + * Documents have sub-fields stored in .fields + */ +exports.Document = Type.extend({ + props: { + name: { + default: 'Document' + } + }, + collections: { + fields: FieldCollection + }, + /** + * parse sub-document and add each key/value to this.fields + * @param {Object} obj The sub-document to be parsed + */ + parse: function(obj) { + // parse sub-document and add to this.fields + assert(_.isPlainObject(obj), format('value must be object, got `%s`', obj)); + + /** + * this is a nice way to handle the Undefined values. It iterates over the union + * of object keys and existing field names, automatically inserting undefined + * for the fields that are not in the current object. + * + * Only caveat is that when a field is created for the first time, we need to + * retrospectively bump up the undefined count. That's taken care of in + * @see FieldCollection#addToField + */ + var union = _.union(_.keys(obj), this.fields.pluck('name')); + _.each(union, function(key) { + this.fields.addToField(key, obj[key]); + }.bind(this)); + + this.count += 1; + } +}); diff --git a/lib/types/index.js b/lib/types/index.js new file mode 100644 index 0000000..b5ac699 --- /dev/null +++ b/lib/types/index.js @@ -0,0 +1,8 @@ +var _ = require('lodash'); + +_.extend(module.exports, + require('./constant'), + require('./primitive'), + require('./array'), + require('./document') +); diff --git a/lib/types/primitive.js b/lib/types/primitive.js new file mode 100644 index 0000000..5475b17 --- /dev/null +++ b/lib/types/primitive.js @@ -0,0 +1,166 @@ +var Type = require('./type'); +var _ = require('lodash'); +var ValueCollection = require('../value-collection'); + +/** + * Primitive types store their values and have a .unique counter + */ +var PrimitiveType = exports.PrimitiveType = Type.extend({ + derived: { + unique: { + /** + * we're not using a cache here for performance reasons: listening + * to all add/remove/reset/sync events of PrimitiveType#values and + * recalculating uniqueness after each document is not necessary. + */ + cache: false, + fn: function () { + return _.unique(this.values.pluck('value')).length; + } + } + }, + collections: { + values: ValueCollection + }, + /** + * adds the value to the value collection. Just passing it through. + * @param {Any} value value to be added + */ + parse: function (value) { + this.values.add({value: value}); + this.count += 1; + } +}); + + +// --- Native Javascript Types --- + +exports.String = PrimitiveType.extend({ + props: { + name: { + default: 'String' + } + } +}); + +exports.Number = PrimitiveType.extend({ + props: { + name: { + default: 'Number' + } + } +}); + +exports.Boolean = PrimitiveType.extend({ + props: { + name: { + default: 'Boolean' + } + } +}); + +exports.Date = PrimitiveType.extend({ + props: { + name: { + default: 'Date' + } + } +}); + +exports.RegExp = PrimitiveType.extend({ + props: { + name: { + default: 'RegExp' + } + } +}); + +// --- BSON Types --- + +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Double.html + */ +exports.Double = PrimitiveType.extend({ + props: { + name: { + default: 'Double' + } + } +}); + +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Long.html + */ +exports.Long = PrimitiveType.extend({ + props: { + name: { + default: 'Long' + } + } +}); + +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Timestamp.html + */ +exports.Timestamp = PrimitiveType.extend({ + props: { + name: { + default: 'Timestamp' + } + } +}); + +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/ObjectID.html + */ +exports.ObjectID = PrimitiveType.extend({ + props: { + name: { + default: 'ObjectID' + } + } +}); + +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Binary.html + */ +exports.Binary = PrimitiveType.extend({ + props: { + name: { + default: 'Binary' + } + } +}); + +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Symbol.html + */ +exports.Symbol = PrimitiveType.extend({ + props: { + name: { + default: 'Symbol' + } + } +}); + +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/Code.html + */ +exports.Code = PrimitiveType.extend({ + props: { + name: { + default: 'Code' + } + } +}); + +/** + * @see http://mongodb.github.io/node-mongodb-native/2.0/api/DBRef.html + */ +exports.DBRef = PrimitiveType.extend({ + props: { + name: { + default: 'DBRef' + } + } +}); diff --git a/lib/types/type.js b/lib/types/type.js new file mode 100644 index 0000000..c46355e --- /dev/null +++ b/lib/types/type.js @@ -0,0 +1,36 @@ +var AmpersandState = require('ampersand-state'); +/** + * Generic Type superclass has name, count, probability properties + */ +module.exports = AmpersandState.extend({ + idAttribute: 'name', + props: { + name: { + type: 'string' + }, + count: { + type: 'number', + default: 0 + } + }, + session: { + parent: 'state' + }, + derived: { + namespace: { + fn: function () { + return this.name; + } + }, + probability: { + deps: ['count', 'parent.count', 'parent.total_count'], + fn: function () { + if (!this.parent) return null; + return this.count / (this.parent.total_count || this.parent.count); + } + }, + }, + parse: function() { + this.count += 1; + } +}); diff --git a/test/field-collection.test.js b/test/field-collection.test.js index 0ac786b..1f1b927 100644 --- a/test/field-collection.test.js +++ b/test/field-collection.test.js @@ -1,4 +1,4 @@ -var Document = require('../lib/type').Document; +var Document = require('../lib/types').Document; var FieldCollection = require('../lib/field-collection'); var _ = require('lodash'); var assert = require('assert'); diff --git a/test/type.test.js b/test/type.test.js index 767324c..a028273 100644 --- a/test/type.test.js +++ b/test/type.test.js @@ -1,11 +1,11 @@ -var type = require('../lib/type'); +var types = require('../lib/types'); var assert = require('assert'); var debug = require('debug')('mongodb-schema:test:type'); describe('Array', function () { var arr; beforeEach(function () { - arr = new type.Array(); + arr = new types.Array(); }); it('should be constructable', function () { assert.ok(arr); @@ -42,7 +42,7 @@ describe('Array', function () { describe('Document', function () { var doc; beforeEach(function () { - doc = new type.Document(); + doc = new types.Document(); }); it('should be constructable', function () { assert.ok(doc); diff --git a/test/value-collection.test.js b/test/value-collection.test.js index 6d7949f..c3c3a1a 100644 --- a/test/value-collection.test.js +++ b/test/value-collection.test.js @@ -1,5 +1,5 @@ var ValueCollection = require('../lib/value-collection'); -var NumberType = require('../lib/type').Number; +var NumberType = require('../lib/types').Number; var _ = require('lodash'); var assert = require('assert'); var debug = require('debug')('mongodb-schema:test:value-collection'); From 3f2edab250e6bf29f26cdba6e7b2ff36811656d7 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Tue, 30 Jun 2015 13:49:18 +1000 Subject: [PATCH 33/42] serialization, some unique issues, README --- README.md | 103 +++++++++++++++++++++----------- docs/mongodb-schema_diagram.png | Bin 71622 -> 141430 bytes examples/parse-schema.js | 2 +- lib/field-collection.js | 3 +- lib/field.js | 44 ++++++++------ lib/index.js | 4 +- lib/schema.js | 14 ++++- lib/type-collection.js | 3 +- lib/types/array.js | 12 ++++ lib/types/constant.js | 8 +++ lib/types/type.js | 16 ++++- lib/value-collection.js | 7 ++- lib/value.js | 5 +- test/basic-unique.test.js | 18 ++++-- test/type.test.js | 4 +- 15 files changed, 173 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index bbb1d70..c36d0d1 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,19 @@ # mongodb-schema [![][npm_img]][npm_url] [![][travis_img]][travis_url] [![][coverage_img]][coverage_url] [![][gitter_img]][gitter_url] -> Infer a probabilistic schema for a MongoDB collection. +Infer a probabilistic schema for a MongoDB collection. + +A high-level view of the class interactions is as follows: + +![](./docs/mongodb-schema_diagram.png) ## Example -`mongodb-schema` doesn't do anything directly with `mongodb` so to try the examples we'll install the node.js driver. As well, we'll need some data -in a collection to derive the schema of: +`mongodb-schema` doesn't do anything directly with `mongodb` so to try the examples we'll install the node.js driver. +As well, we'll need some data in a collection to derive the schema of. + +Make sure you have a `mongod` running on localhost on port 27017 (or change the example accordingly). Then, do: -1. `npm install mongodb mongodb-schema`. +1. `npm install mongodb mongodb-schema` 2. `mongo --eval "db.test.insert([{_id: 1, a: true}, {_id: 2, a: 'true'}, {_id: 3, a: 1}, {_id: 4}])" localhost:27017/test` 3. Create a new file `parse-schema.js` and paste in the following code: ```javascript @@ -26,56 +32,86 @@ in a collection to derive the schema of: }); ``` 4. When we run the above with `node parse-schema.js`, we'll see something - like the following: + like the following (some fields not present here for clarity): ```javascript { - ns: 'test.test', - count: 4, // The number of documents sampled - fields: [ // A collection of Field objects @see lib/field.js + "count": 4, // parsed 4 documents + "ns": "test.test", // namespace + "fields": [ // an array of Field objects, @see `./lib/field.js` { - name: "_id", - probability: 1, // Just as we expected, all 4 documents had `_id` - unique: 4, // All 4 values for `_id` were unique - types: [ + "name": "_id", + "count": 4, // 4 documents counted with _id + "type": "Number", // the type of _id is `Number` + "probability": 1, // all documents had an _id field + "unique": 4, // 4 unique values found + "has_duplicates": false, // therefore no duplicates + "types": [ // an array of Type objects, @see `./lib/types/` { - name: "Number", // The only type seen was a Number - probability: 1, - unique: 4 + "name": "Number", // name of the type + "count": 4, // 4 numbers counted + "probability": 1, + "unique": 4, + "values": [ // array of encountered values + 1, + 2, + 3, + 4 + ] } ] }, { - name: "a", // Unlike `_id`, `a` was present in only 3 of 4 documents - probability: 0.75, - unique: 3, // Of the 3 values seen, all 3 were unique - // As expected, Boolean, String, and Number values were seen. - // A handy instance of `Undefined` is also provided to represent missing data", + "name": "a", + "count": 3, // only 3 documents with field `a` counted + "probability": 0.75, // hence probability 0.75 + "type": [ // found these types + "Boolean", + "String", + "Number", + "Undefined" // for convenience, we treat Undefined as its own type + ], + "unique": 3, + "has_duplicates": false, // there were no duplicate values "types": [ { - name: "Boolean", - probability: 0.25, - unique: 1 + "name": "Boolean", + "count": 1, + "probability": 0.25, // probabilities for types are calculated factoring in Undefined + "unique": 1, + "values": [ + true + ] }, { - name: "String", - probability: 0.25, - unique: 1 + "name": "String", + "count": 1, + "probability": 0.25, + "unique": 1, + "values": [ + "true" + ] }, { - name: "Number", - probability: 0.25, - unique: 1 + "name": "Number", + "count": 1, + "probability": 0.25, + "unique": 1, + "values": [ + 1 + ] }, { - name: "Undefined", - probability: 0.25 + "name": "Undefined", + "count": 1, + "probability": 0.25, + "unique": 0 } ] } ] } - ``` +``` ### More Examples @@ -103,9 +139,6 @@ Apache 2.0 Under the hood, `mongodb-schema` uses [ampersand-state][ampersand-state] and [ampersand-collection][ampersand-collection] for modeling [Schema][schema], [Field][field]'s, and [Type][type]'s. -A high-level view of the class interactions is as follows: - -![](./docs/mongodb-schema_diagram.png) diff --git a/docs/mongodb-schema_diagram.png b/docs/mongodb-schema_diagram.png index c7003b46ffa0c016c59f5c18899977dc1920b274..eba84a3c6ca83097ed4a63dd50515f5ea8d6c56e 100644 GIT binary patch literal 141430 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 X%ig)VM4H&`*Qgj}SGh(41ZQvN! z&Q`|D^!Nx}0!QTHN9B0Fbi-Fobgg}DA)68>M?D*$I$uU_yv<8MhhkHs3kU`vz=n<9 zS@B79$OsC3W)8jtM77uOlS{XKW>}6po{3tSN$hvQU$bz%do5hA~>V>&{zNlf3tZm9_(~#-X==q*C>WS}Y!$U;5YfO)kHPqA!hpE$*qa-VrUA5Kc-w76Z`3 zmYH=cbe|i4BsHM6nnVsdD%?6+Jx1W$Le$1fp}v&TF$A)N^7Il3QGCu52=KY!sdI`h zS^Pn~N7r1gsTvUyj(f|%vLd2LvvHi5Xe$%zILzU;?v2Cs?aX9nW=K0(Bo4do#r0*l zW(WSaf@*8EUQNKS7H~*`ZSOx^T+Dl*BF#Cns2cOy-iw9FLG%wOR3*_%;N=^&*?Rq^&RN7R5R zBW`BI%;}?QGsIu$Ox)8W1$)Z_5bUOBnmVFq1T)eENu8 zS5vX7Y9d1*=gIotBvKycltd3dgEG4Q%XL4ow+BB*z?ry6%jNi39Fk-&E=N=h=FA)z z>gCC@=YFma7vP$3La#@)?8$05dKO8F6>*)Q{4t<7H{nK^!}0S{tct-q5UQxj~~rx6dUS{Q$KIBMN|`Bh5|zkzXkR$KY4sc z%oo-gUkmPDuLxh#Yyvn~aD>^}>yWjAJ>xb5`r0Gb`2T%gpo3$p`+%wXr1So{>JM|4D z`B)w9BTNl^3K6tF9+ig^yst`@a(;YY&FF$H+n29i-5ch*xDW6P7KHzkR`4lK$6!_^0^^b|!U>|Nh~(&#xN8d%Uo|WrzFU zLli(=(62ZIiX%f!V|LZl=pIl8+PpA?x!FGuCV)f?TQztc z4Zisc0uy*>zSR5qm(-ADZZGHyL*-&v=McXt&=JsdBqEJ1m_~Wb=7q4bCwLe$Kw0Bv z0N6&lSqHlSP*vUmB#(qU<{Qys!5l*%f_w!U$@0dVKtaP6q4TeUt`0HZfDUE#LV=oq zHMCY2VEkS+Fa(%Em8Yy6*S~v=T*&-eFsa=A1A_`^D_i_*6Qbo1+F~WGDGQ6yu3p&W zMyD3QeTp4PJJ&DufU8I>4vMC9mqG+Fi82E~#MKum^QU_YosI7|IFV`=x#ZG%|ansJi-cMtwBaybh_`S{7Rw$^<3MLcQEy?QYcU$nYf|Ylf6xYK30}li@jw;Mysgp@e{FR$^^hWTbHrL6+~U2 zy+T1STnJm?kee#@Xs-!oV?o*iI)}Fr>Wsv`YS%>o^ZlWpS&PW<+z7iHS#biJ0Et(B zeok%(54Rai`f`D4h=A9n6x()?nYc~?;>8Xi$eidZ;3Diue0X<@85c$MTLTi-BZKu- zYHM|)5|e1|op+m?v+_J*<6L!1kEL=KdZEKOl`;z$l|7&dvNkV(PwGG;y`s>6Y|`G5qm(bdZIQc4evy%#b47p?JU-plF5RbH+O?2_|% zkO{w>AF6~FwuS+;iV=fZM0A>R(~Md{IX)XY=Za(LQy+mVx=xd;Oz#L5&2Nj_*Ug6^ z=dDIe)1YTgwk6S3OqcNg`1%T{thTLfDd`fV8zrQ>5lIyUF_2a|Bt;qtNoflZkW^4< zq&r`bMv-nLq`Tvv+xva@-gEB#zcDytpu+?E-Fxk|=6q^GERSZ(2nvE=W5oDXZf`m_@Uy3DqQ6SXRL!Olj0V$rBM1EL;wE&sttNGx>I4*>HmK~k zSk#@1Gb=-hR$5kn={>7RwtOqqSpeVCuR& zXF=T!EclD}r~x)_0MI`|1f?KsS;>xc5(^OFz2g$|%nKH_rx>B63emT|L*T=oofx+} zl-N|^^OnhV$?T2Zo6jeZ^0eEf&${z5^vrwE?J;6%`V#}0@cyU%>PTsx_W5G7S*uA! zxHGeR*gj28eDzL3QAjOS7mWm;Etd~^!DqqGm=SvBch`9@p`xg-`MDmJbAfp>g4#Jp)Z_qMp z`y>hFf^^hN5KxPP-TCf*vfYDNCoV=N6se}4XZFw9Jhr*@@cE{@?h`Uk5_oPKnAI+^6sw; zF6*2Gj_f^-7MGSydRrtI%H#Rq47cz{Y-KsXoQk*1MEph87q*ixR)PpnlJL!uQ-U5q zx{2pq-k;BYmh28bZ0W^)x3z~D>E1+yC>46f?x6E0V-USK6IE&>P8ff3+osy*MDfKI30Y?GRq$ znFuA`hqszGv4;>s6m*q+n~$|Is}_`S4W~#-#|ae2-Wy}EkjQrRa$Jw>gLg*Kd^Bg5 z%O2^e-U=|WRcgN%aP;XloziP|F>Z{p(=$KWwdx8?9XT)Kmy|Ua#0#!5e|V3WEr`69riaRSR&(Zquv%gpkC`hp*8|`+sVznOVvW^^) zP$?%}t(b@dzzw}*j7}_SWVhO_ubuC--m-qwVC9s?0UXoMJk zyJd-Pa?EEt9glQnoguxA39+MbrT!2i_8)Jv!89G5Bm2p0cgR)6UoH*Jq__6mOQ--9 z)w?~4d}UhqoH@zH-p|FDG5BP(+ZZJMY!-}29+<^4IQ`hJT0t-{Yi3~BYZk!E>Rb?f z7SC())ZHLf>?w6-yIw{3K(qI{+V@#ogYloUG6rl*#%Csp8DR!9!4+N~+6fHI7X?*g zHJ%>aqpVEob}k_Al&J9f*sgDIn%+K8;g#NATEX2j>uEr-Sa?0Qxq`d*qw=qA%CU^g zWxgk>@dyf6S>!{S=5uXfV8tR?Zx9Is!?^PsdZ}1I3PrUkvZ5$=vgv)+++Yc4IM3PZ!uC{s;35G8H%$gU*p_b^g zAWP_k5U<}yLQZEfpC7kapOdui3K!+Z7#1w%p&b@XXH76jHmkhIqbod0si9n8c4?#- zbC0gWYD))|`*W{|z=3d6>e-DqKPaU?wlj_cG9hq zp?x{j=2}qksnA-hUH|<_AL`~9`l^W}Ol*=)49@Nb)nTM2yQ?3tHC(B^_lo%~}_L8TSqa?Ywp!0Mm z&^!1z&4+WI!DAuSL25x`<;Q7)O8XJIz?r-PqX;2{q(3@4`5O4YZ~KMK`L90(K7eYG z;bKo+eD`)S4N7b6XMB#{*N(nH^Pz7qZ~4Ehp-4B2)^*9Q9vc(9k)yLRlcSfenlSAB z7{ce?z+S8qFKjhkx)W$8D+D-R?vs8Ui-YXkBEiaIG?m}PS=9jiA$}fDy%Qvt?eTrx zlbeM6M~`1f|Ah2mK3!|(Laq*Oy^20#O_+$VbuKoowZ`p*PIw%DT9$DgX52+3(ya=- zE4dQ$&Ob$hYe}1n=0w6mjg^%In4Xi8W!&fY!*x;*dGzT_!u4}W=0lAncl(C&i3e(~ z&i9>v=6Nm(WZF+0KCDvprV#YTxzDXz1n+lORWLPiTvD&2$ytT#nw_ICGH}AZry2MH z=FLhl2oB4fo2qSgW@Q&lou{j=|NWxH6U|6oFh0#fTqf83A-VO($Uu`!G1pP5yYEm( zq-oyA(IsapzUVf@mr!i0+qKz=XLpX{iLA)K8(k;2dbih7)V=SbYdGu}lZ8bawl2Wc zC$G{M+|OE9Dx)s>`;rv%yl~gEdN=OQ{UG!Yo#BJciF*D#5KZ{fRd9=HKz8KVpPxK6 zURFsCQ}Lf)Da^P zLEO-V8;zm6-?+)*Is0P-Pnm33G91HPUQ_F1TJ5h-5ed8=+uwK^^E9%-IX-Y83+Stp zqDG$029b1ax>`e{gy(n>13WmFLfFUB=z|2OK#st{>&(4wY3F##G<~+Al4JRjr$QT_ znxH%X%7sSRp2B*(gA>gRu?vl2UO|fXh90}#fr@We^e)MgreX6>%w|&E>Yn^|efvTN zworADj|!fx@m)6b9F0exKgJYd$4d*%AM>wm*%L>7q&}0K6jB)uB zsRtIBD&$zd%FM{lsM=#Grupx1e?U;nT!5KN-XF8C-Uw6rMkmi77c21KbtcD+0-8Lm zN?^k(10TJ&$r^oz*MNkGkvqlCvjq!BEefCC7B#tIc6`m$XICfaL8o1KqpD_H(&JGg zQRgcnWib@Sj98=@xP2P2B>M7cG&wrdQ)X@ZeQGdr72x zD0bm2riJl%bNbG?xgW2BqfJ?Q_%UIkF?%r90-edq1W*#9xi;fXMm^fCKLtdkW~d&5 zon!a>`6welEwUs|wyk;^lT9IY$p$U)nw`3`qsrBaEQRaro=5(~s8{yJ0Zt2d|83dH zVbb{d223lLh0-Y8B}=(|Gc_*kwI314@Iv%ZeFvm<^-{RJMG)KGvWbudrfUx%|Lx1CjN9RA2VN@tFLUzlx5)Oy+Ghzjta2*WPz3#L0%ZwevJg-Bd# z1LKDr&wC2pTg~p(sh7Es`~5zk2$;DYiBI-qiVu%Dbs3l?3L=$ceWuU>D8hDy>^BzV zA|q}_U2ggO^wVX(_UIkq3p1VE5sH3suj_=apG3>bzj`63Ksrgwr9$Tz(D^y>fy4we z@3Ve^P4RgY^w^~wjrljcKD9M9s~?oU_L<+`3n!*153%46n!_a~S4jHXJKKxXBoj?z zYeN%-BTR>O%Ar0C4(`P{NNL!b{wT)d)B2t4N+*XlDk3RsyEQHLqQc#tK?WW->!Ge9 zA0&gj6vm0Da5X_R+z`dg-q-GZ<)h>haG;H-k3J^Hj~$BI0denk_w$Rx(@{sjyMHsf zCVBK>PdnaGjoC(7T%Av7SaK=bB)K^}SstCj`>O{m;!Jm^5%p!ppad%ZN50J(LSB z0rZ6lnfjZ$`99>suZ^z{Kcno@{9O>>vZKR~R&%#|Zwi}L^U@sQ7}*UL0j5@(C^=v< z(g!!`41jmCmF*P06I3)cq0Eg#d(lYRvun(YgCg8MHJ@%?MVI7-ME4e&?!F#r+tObb z<3C>FHfH`9F56gZ5~ANc3+0QF^7N*{POZ$rg8~eQcSkVN5qrFlAuT5vX3v~J_r9PK zN%xzX#G$|l4) z&yYuc1jul`$u-&90YgunQ&6b9)2!*)2)? z1b|}D^sYMuDCp8RvF@&)-$Pj$mfSH#ZRxy@$ZoNi3Xx7OmoXe?L{K8;3&0t*X z1B4e()SiC6G3vsiLK)G|bd9F+k`mIwOKm?;XE^J+Q@Y_wZD#HBl7o+0+Tt~wAN~|W zllJ;rj=opaId7FdrQbc1sNv5X5YQQc^Omeo*K2c)c771Lnt{1lBtT4w+N@8^4}Jc} z`2<0cL`n9#+OvaG;@k5I_x6wzErl1?(mS`kJwrWAZiR$HbbwueuX zC%JRKnPE4a*#WhZxpKKRUbA$sd4jF^GhYjPlzTZ@fU%pRryG&Q_Qi2aS)BY-V}Th9 zdhVJz&X|U;Qt7sZb<-*g_?&?mLbC2Mtyj7tBlWG_om_Su3Imu3$DsY=cX6Z4Tz4|%y8y^y%oTB<6@{zYEQv+j>vV2VrC-@*GCy| zMUpA79tJ)Rtpf%58pI0NIbAplV(#*`KKmXp-S@oBMiM<NEyE$DjL`#utB`spRhRzq!e%?4D>j{jFAoPcv0<1=M-T2$HZ0-8@BwK^ zcGcStnPSq?wYpr%JLNXau4sjiQBU=K8QKg4SKMj#mO(YwNo1q|eAMD@5|NE%mBJ%~U&Bk64}?`K z+j5Q2!-b?l@fD`gVJE1y0TpEOut|{I^aKWKgxKiP9sDa_f8$un+E%EJ<6sb7W!U!d zRW6IC@y7{~Vakm?ez zz)^}WJ zzP`zmKB{cHlJ$#gZVsA}Dl_er?z6VHgKw+e5^^ED_m?wO z*B{Q*{*-K|5V^NF4pRcW)BOOKY#EM0&UV(*jA0uWaJkM^w<|3!oOl8~JYcT!lZ%uD z4HiZrZjWai{;SQE^EH0;!3IO&#J5Rf8aB|f)c*1t6jS)oht7fxw4c4bfJSPmfUZr_ zQ4Js1F1LK{35+AL`fT zfBTYi#JogK*`oSUDJ28v(M!>m2admWlnTTXdbjpreRsQ**=-g0zW;+jgKEzJP~ES1 zv(Pq_d!FnJbmHgOVP{2#{rgY+=l60Kaj$davgnKOp#Nm+f!^Y|dI4AsDDUNt<8=bs zk^3Oe(7o~&sZ4BiQYqR+;J6U|M5*qFRrCPrE+ZpP4fR-l`w^LUqb)&$%SRnaGN81B19U7nfV!g5`onH=;HAq32sdv z7FriQzkA(@dvVS4>s582X*lcXjY0ljayj2KVp=h~(Fa)M_euYCn=K{LFN7wnzIt3| zd*jh!-)B2mq_#s?@AY6)C&E?pyk9}&nalg1Pqz;ru43oO$G&c5ruCn&weS&_DVM#1 z*R)6w&AqNz(BZxMUl*?&W_+|AnyO~jYpmd2`fCu^9l+7$Ma$735O*sHgkU< z?*Dp3Ov-Zdjs!uX|JT1sp@tP|hsw$o_|MPyuf--84(~PO#aUmNCo#zfNGfhpKIYizwtA_1gnEOuLAYYI~9Fx5^5d?B_s^zhQJ8W;A7^|Rk;j^+Nms+^C2PE6CobD%({P#^SR~PHcZ2cZU{Z#(2 zYkk%==pM1t`+95Xkx1FS^vucdR@zTEmE5-OjQ2i=ydlEwyT`1LA->7HCy8sW((C^1jyA9zx( z2Kfp|?{x}?PDngoY3HX@w$aH^zqPYLwge$3!qV)6qEWq1x?7rs4-q9$rv{LJI-AkE z$P0Zb{W;b$YCh0Z;q;OEr78sL+9Uahr7I;P z!@Dq1b!y?3G}yuidaqk&Wo>my<++pQ!Yt9^p9P|;x61XOvtPpGEggN*K4jTu`!(X_ z!Zx8g6kZJZagE!P5uO*3;xe)YJex~eFtec)CUBZx-hi+k36HM5h2F+a2&B?!->8Eq z!-ZTZ&G5MdTIih0ED(MuHu1o?deBu;*Uw0mKr0##|3 zNR&QR0yUAH9G*ajS_j*OgtY0?ZN$bMMhoREl;89EKzt#m;yhR+q#j>A z?S>&7Hnug$Ne0Do$;K&+np%Y*^e3R=FIa+2tg5W!Z>#zrkNqao?HFu2MYJvMMtRlC zhdo8vY*EuOYQrp<6f&XhvrHPTPjJoqW3lzasNul~zg|7tEg3Y%PcT6QybJ4}G}Dju zojT19zIKWxBpU@$OJ8*zu@!4qt(nT7i+`*uE3c$z`@xneJUZDdMkjl@u$^~F0{c-w z4L}AA8zDJuKzOWylF*}leqK$e^H=TuH2zh)QSo-E!-aGi28SUR7-f*H{)C`D?5szD zcn37+J5X!B4<@m7cB_Flfj8X~8D8U-V$#AKqvswnC|gzCFe6C%$rZ{+y^hSbPtVW^ ze-~&S4gOR>w(M5b6y|vgck=n_)hkTswyKjLb`e|S^$6;P3V^0`&^W9-r)0QI1|~($ z%|aAHZ7Y6+853J2SQk4ZsD)5f-3wzS(0*3Je^J3sG~VYbz*H`Q;+qqd=>?_yTixIm z>W8r#LQsOM4gf#2C9Yr@9==J}2&sm)^TGQs9l32YsfcUjQHOA>S?tvLuTLX++oj)c za=i;4gO_4qZ~_XaA)c!B2I?_|5F%`}KAz&fJGoGg^a=!=@@v$90(-QBF-eyFnztvTk;9zwX?7BwV7z^7%}Pg(T(lA!Me|%ZCm& z=mYWg=$`1eK82N}`He(QBq=r>I08n7F<{=W_8&Cc`RXqJolBsrB2F}C%Ia+W z)U?XZL&>gW$lMOx4z4ilAvpnN=@@K|hYkEF!68?e1h~fuB4LXC%NCh%DnVP7X9qzA ztG`}rxPa-`(E9H2sgrs-oYsARp!2C=<)mG>MK>=0?)*W zj|MJ7&4^Jn(%F)vaAga`)lquz$1%7&)b1-Ies6rVlYKB2c&d8j@yijpr)^QMvS=id zGU=E!Il_6YCm&^2Q~$lv)t;8G$4h9ohBO(@Nlz1-$NrMWQ3`@NknpG$O79|_W) z*15`%PKBO60b~4D#M`Id+7LT7?LzF~VEC3a3;>DIATIaP3deq!YSKCDM=8B3A8zdN z+i@9;ye?t6L{$8Bk=L4DL>f5MV==IVxsUTeC%gOY&`oLd4BQ=><;H``Z}A3k#zPQT zZO7IRiz1|o#GSDRL%?qPsVVjDOT+N0+|djb7R`WK~{1nSz)5+5I-h2(rFJLxT)hbmUJG)nbc=(yPPT?t1vi}O~2Fn?iIf@e%)gx z3C6*=_!xkooaYNx_tXa!$FS#|)Bt*9*@HzV_|cLNIAOytB)USjb0P;{r_j|7i@GUl zd}+IH0s(7u47|g8?1mKRMG<^WWmmz4VZ(_2v?}fl&P^Nd`2!Mk)|ogL#S{iyOWDpu zwc-bqm^9x_a(G*_ULy}GIzdjMt9#{1l#U8)V8ij}WE6fkqqJYT-5)CXt@*BVLFW*J z06O|@fMoSgn@u|#so1M~V4p!2$k3MxAjA{cH=z?XF)ZHZ_wShmr{?{=Z|upYeJ1*9 zyZ(lD;orUqZr?LI?gEd`KrgEZRe)*mK++g8mAdfGRex+oZ?|}C#-ldbb-L~CTYx-% z#2yFpq78!^qPQ=V7-`{}-MztA{h`;BCeKGt&4eL+ZxzHSb^}3PvWE+-Dsv=4^d?*K zmZ9++LALik*AaTapobp+#POc(RrB!g5IR)<9>%X|a*=%OFd;!N@dW;yKEP#*-*j0s zSwi?Tb*om%-btI@Z*)?!S*L2$Bi7{Q_{bd zT$bACD>N>qG;uh>%xIwrnw~HaB6sOrA9Mzeh+WiuMm2un&E(!cb5w_ zaM<{`Wy6D@RL+Fzd{cLkZH*malsNt^5_z-rb6A9-0|W^#+xOcz@8y^wnNqvB zdDE7D>~4+;*SoPkb7VBocBAeQj5u@|%MN*iBqay0`<7-R%Xg&cl9wf}6Z)=b8Wb6_ zWg16NmPMZ$~h@BWQF>KA%?{3j3y)xK@aOzIrMu z@X~AL`goK?C~9N#sH&-mL@-8TCHYAUt-b2V-}b3uRj9>R3~6`NFhkkoG}LKkn!ihl zB|Yb-s`~XR;%=*%yGPq)nQp3)R~wIJf|TCa#G-El*<{~f9pb9mtr3tGLdj<-wVgvk zTyqDd`w5#t=CM_HCT)09b`kWEKV+%*+(2Q%CVn?M;%f%et&O)EUZ7*KCHod;^q8Gv zGZ~I1@$~cZ@^NzAk2j%q9ux==D9{Max`Drk-SVc}?P^oROy&Z)G}%lG-dNWF8^yk0 z{d@g`btb#1RC#HQ5tiG$XtE(GrBbz(HxgjnxnS0(XDEs}T3k>Lr&d3ci!zW6Pb-zh zGWE9SvYIk7%oRPL&$yka6=Sd3`nMXDCK)PnR4t0eh>SFa<3@TZd-cs3+zq`Isz${R z)YacC!PIWa;=%f#$7ln?PpsnwM(=LLVQSqC7n|n0M6{v#bqI;?3z~a zWx{LGC;+H!gjYfQ*VhlOELb9;s`Www4^N6_4u%N`${!hjcUuK_8r#=mK6EqE$!e6R zr1YCmF%&lCN1DdQ+n44Vo`kH}raDu#1v8uM%XmR)x6FL+^Gd946tUNSbl8b14Q0)n zzjf`xvVLdPu7mqCeK<-foH&pCF43}^U|NuQDO`VXi6r!ya44mfGI7O+%nitpUd*>l zNN4A#ka$9_vIb(at)|(mp9DW{hd0aYb9ke8e%C+f(wipcrLvla|}v+ zaTGD(xXaWrLFY@Z42~JWA9tg*2u6y$&DzuV9OALewOg-9s%a>pIMn-b4O_ghWRtPZ zAGBR`f|p}T8h zZ+W$*UVKHn>^sAi%k%BGBe%}Y$3kEuKWiWU#PDPzcbCYwHHD8d;R+9@leGiB&q)WJ z3vGE|LEwNlBKWU1{0|I-LcocQyaMGxMa%`X7RGI_XK_>P($2q~8 zb+4_?Sk24)`16^Tx30zEA6!DFnCt zfr0be!11ZXrt;`1msiBP4er$P&l&0=R_3X`9B-$Vj@iXh$b&?B%i+BUdrk-5XQ0Si zxklT#i%ER8{>}aE#;b!8h2n7HQ>3>Id#$!+9<-RszL9dx-$tO#hPdL(PsU=dzXAw7 zhnVCZX*=(h!dY&Mpfhu$%NV^zVNG)o)j&V@O`!ylO2vm9L%&-ZIKN~TYtYYP&PJIt zVwoPHPok-i4iOV2wkVltkccgFe7a-PWwt$;-s{h2XT{((8!j^LQnG@S)ry8e$&Utc zgC66g5iZ?6mmwyAHB53OR;0wX-8I8vza796!z1JOjq96eQS$D)ZHEs`9Y>D>FKRi| zOC=b~@_ZZcTm!?hc}p3N@#UO5Nznx9*EH-=p&7xh{6XjUYtN2q^RqNaKT)BD)_avT zx-IMH7lP<cf(^L&;ITBNH~WTcy=8zkMhG3Tb-soyF|8*$;I z4Qx(ISR4TX1KKQ5)}MgYetM&#Hn{XlFuVRe%IVK<%@Wp=wzOM2CZJ$pkS~~3SPp5E zMM_KT4dFJ`kvgsshNN_@U8sLbPaCra6u37?EVvn&dD6ZFMmmp{IciZpSGgxGSu5={`u38z@jvBK2N_rn29#@@XnxoT)dW6&Nid+scn?Xh)tdlqO$IAOcZ zJ+vYTjBf&}C9GUyJ-=}VExyy!-yKc}xxf)k1Vb#yRE;Vt$Hz( zv+#);`2sS(*;0Cgu*qChQ?$$XsywFyd(Q2WYXN-sIF$8`d?4Y+!!WCdm|M`&{hO>> zqImD!eB#-Lc{FUgNzO~yTn{)hCb2YH7Yyay!V6)eibxxV8rb$E82dwTW~s^oZsi&W zjo6nPgLUuYt=#ADHVy3rW*`GqH0|F%Z)tW9cH&`VXpSJJJg5sM#^O-cQ6rGwapRG6ZknjqE9=s9WLKw}7pWe;W=3xl*nMZ)pgM$bFZL7d)Q=@j2%O8~hT(NH zKUoOCC0LFv< z2SL=ods6*PI{IwPUOR`4S;XPs^tjlQ>xn%$fN0TiM&1J?*G0DE^42JhtY2Zm6& zTV$JeQ2JOlr=jx%3A=V(?Bkq?z^E~Lf}*y#H)Uge2Xi>cckTzp)@MQMtZLa9O74H(*JvBwLr* z7(MKrHh7vAT|#VaJ9JaIBm;4TxzU=;T-9b;qFlH6mDQX)S+SS{Xtp5v4TbB&b z@!22MTMpRA|E^P>&=WNNNlg=D5eg(O8nYX!{s#B6(jPG5F%B#08{Ki)7D$vLJ*HYn61M|rQePyw1ZL#97 zAMkGwwHy|Z8M)^aMVSBX(2Rax2Ls!uAc<&q8SAOyU#};n6M@9HR8xqM8wczV5{6X@ zM`-}>^1uB` zCiDn-XaUmoZ$zXU;Z(s%Vh3*CRX~Al;smUi-m=O$?jt}8S5DEZ1gng9PeiMLh%1Ap z{KrO8n;BAOr|%zwX}#S5IL%ckbRKIS7ql=q0UT<7gQXu(a2sc2!ZyW9zb*=rwyisM zLA;%4fE@FqNKUUIL|`V)KD~_@%IpAVSOqd3rTLzw&fjk>oWQuv7ZpASDW(Ww0`^H= z3aD}UOI8)FjCw)6RLhOn+T)KMTK8mV{frNgp;D^=2Dofnc3L2)D17wvBlwF#if51m zq4pFpLDG+8$W?#}vyzlm*|ZM{h#mtt_3kT5p`-c=TO;!7SZKyv0W_z4>Jd6*D(b%Z zD{&UE{>P6?ea=oL+JC3~mq*-(??=7(F?}%;p3w-&K2R`sWz~(SZ_V z1PZt@KrQt|3GmAFY>VHzv;7c?VQ2;Spwo8DN0LLp63SruL*?=oGF3V<>6K7N&!Nu~ z4hIA=UWLMe$CGa3JUBe&i6nlJxc+*nLi6>amNv7u_K1kGZ-L{%dcjP+SPJ>9FV zgxRL~N_^ZfzX z>7>-7yk%{Ww88`sLh$gdFb3t~Jo5yyb_^=q26ALp2D zHNh0%QApXb9vQLu8leXQl4Z1h+tM*}!(COr>Y^pk>_``RI>TKEZUJOefah}7S4Rs=yah1#A0C%UWL1QMN@er*#%NKqhJqLn!{Ltg8@ zecjH&M9HgdmM1vb_f=Zd2YRqYr8KYyCh0~$7!dOs%FCp24D8&Hp9zF z*WFc7-FHV-$34XGvl)q9L*yAaV7tV@IgEOjc=55EXQ9sAd2I7>ot%7kl zgqMd@VrGhQ%t&vx_<*}yQ^!spKvEaN)^OXc*E=L_C?{`R)Y{c8U{5S-hpn^zFb54r z&qC$!q4wK|c=?kS?et{e3~h1c%ja5HN1bwVTTVjyW)Yg0U#>Id<@;f^Ew{)VK1x0& zJ%Ms`Fp3Tj6Q4WZ_XH>CLEOotxx^_`kn4jmM)_IOQMl1A3?<1i0Qg@NVGIyyx*xgO zaK2gbv`mE~B6=3&EUQztbDZ+$U;3Jn95P*qPHz}Qd{ZX~B(&pi1`+L7$$Y10%Lw_T zuL4n|Xg1{9{|u4|UMb;^XL5MgpNMsagXw(7hOE4msHHpJ~1W;!0q~%~H&3^O}5o z;88hAYTORz;fAN4?dyC$u2`g~G<*$1@ETV!LYtA0U>PR2#m|}24KLl?0zJo%+xqUi=Lb;m<35O8Zf!@pdYfOjeOGOS%^67iOKep?!7TTgEd@!AFq z32RkamS|uU$tToxs!5|sH0>X#ogj4x1$umP!tBk*i7dA-qhsOHZeKwi+`3M9)sEwX zrgRF&F$}*8veBsbZ&-lSVV<;ssg2Loe_A-uiY$dc1Fy%4`xdtp)R#G{ za1Hd%FXRQVj6=uW=tl#vLUHMY3}>R+9Q_*@1E*j&9)AeB5Vq@g_*2W|{aEbW2#1GL zLT*jbg`s(b5^__n*;lDEkFX~?JTF#7d%;3@6!2g`rkaRT8I{v>O3^4bE^8QDTH^&? zq>bh5kzY3q$)A2F$g|S(ywQE#V`;;qsf9AYxQbzwa{-eAu(86W8^nuc&(`a)du0^s z->rPaZQfosyXvNqZ!rF_s-OIATrBwk=k1NdAG9xt*%xHg?K=Pqn~+{sU>v+!;ye=} zHeBw0GQG#Ilqoz@ebapV3vbh)tM}O#+Y6!&*k-!p2XD66=2f^G7D!zsXD%4P@LHFL z`Vf-nVgoJ0W>qQY7gWR^_q>6}Y>>%EoNS!VN9fj7Fo=uJ=l1Jc9FYU<#q`w-S}n8)VMUeO0dcrr}mMQ5iGYA)?av_5i7By2NwP({nre%ah4$Ey&Q7 zGR30;`;3ohhq(gmIl`zK*z$u&#98?UCVaBx!;pUizDzT>|-;rLp_I^lO!nqpWj-?aUn^f$Hc@I5WEul(2EE? zbB4Wr20NJ^pRVlsg=qsxocEgV?}(N8UT8Abd&4{7TXT8=o0x{IR(PZ4!HY zo}^N`DsF>e^gG$DUT!p{mL?;%rOs{~B(sgLN9z-M>Q(vMxXh6R$g$0m)-cQ@<>iGX|Br0yjzcVYF~CYDves=kp3`^(+?*h z_Tx_8BH*$0Hj^E+-X8AHDW$*7+gT<@PuX$=Te+>B1@-AI|2+p?$M%_NZ^xM`KC-{kG#pU? zn{V!aF2O0nL&KvcUwuwRbJdE3cN|O$ZZ27NjX!>B<+eONB}%G}WFb&83BYl{Ved)f zTfgFj!xjB9syWn#k(pqbEGcF8#!GQtilCcr7e|dY(({)%#$mn2L~@OpycEUedlWp7 zKL#yz%w3xhn(ISy`| zozu#Gi36NgQYfFQ!_P8ivrmI1g#lpmMGiFLEorA8is3a~&}qEBgx8{cgr@ zcq+2a@Kfg094@YYN{_tBW#`_`{Z*~sMDp+DC5@k&SxS-UJylq)7jY)FxPXhI1yUw+C?ho5AqyYZ7N&A55mG~!F)0TX272FF$k6g8Q%*f^L`riIs0-X!zST@6w7gG5^Cr49rk5=%h@)W*i=6z+VW z?tZsDp6)BxDDSvSt(c@Cd(gCte-doG=!=G-Mu(EW&ql?%>J+vZ=#bK?hCgms;_t&j za=Cf<&XFF+!z8JIAsk|Cd7qmn1n5K1YrN@I93(agWeoRp6iSvC%F`^f+b9gQ*`fp~6EeK&=p>aVO4^JeEwSBsgj$!6tBhjoWI> zq1l-P@y67RkJ-aBt^FF@m*N~lCM;@5{R8jPPpGFLhJmIlF3ih!KFLLy236L}zt7cQ zo9oH=t2sgr^Ax0O`x+F(7yRN`NGS0U>DAH*bYaoGDxptd=)%`3X!JfC3 z+=+L6P-O=u0$W#zSlU>o7};J=(^k_A-w35nW7?L|i8E%!0UmA@W;zaG&FeJMZVo|m3iiK0h#3`}5T0{*a!(98?HK@EJ`h9z2y&R|ON?{EZ@+NVw02H~e7=)z~`X=3tx@tDTv zCaZues9g;E(KKhgpW(u!!bb6<@Q6h})<%g_E@(|p8pwgowmbr~piCq-( zNn&LbotE~lVblL2wZ4>YGdOjE(c8276_Ho1 z8o6-=HD31FtZBx$fQ&GkxAC9Bo4^lQlV~@WYAwgGEgB1bEAAelb8U;$UEXq=gd_cN zokZZCgV*V!a+qTIebp>n=t}#VWRngoUpaTUKJZi|7BGc3(m%W%x#&=o!c zS=`w?Y>1`L3l`RkoQg8B0HtQ`% zh;w4f$n2^&AlObv1wxL~ict^j(isO9GHn?h>d@FOS)3@n5x@OOjwa6qL^o~$ocsk5 z^UYih8;#T>Z9aHd8kyF`feXI_G!RroegaS6Y@nGdrPE?M|=Ju(obe zHORWT8LFgFwhTfv3I&TUNhkoiJh#)DbAW$A{jQGoFE2g(hJNpMmMVHN;gD<7-c+)7^Pfnx}JRVIM_W9 zJBJ@PtkB?P#^qS0JJb48tcr9R9AH+JY@=P~Uf0{ORgmG}29^3|UyD<{NUww7SpNW5 zhezwZZ$QWw)_&YSK=LI7OxJjD0q;Jz1ULfE1x8$Cx(8+(mk4~Lu1en|t>ZQ6>9I_}sFm66uA-4I3%nYnL13VA_tCNx4tm3LwKMRT6% z@}nB9B;ieWVn=D}mRF9v2yTf@JZM_*YL8j8JU^dCQKhv0Jgqp+&Ce?rzfbgqVwrBf zb&TW-pyy1vInF}zm?sfK!ID4xy6h3mL0G=HjwligNxSbS<;^<1R0s;HQ}D}HqE-*s z!#ZjhEIgq2F~j1e|0z0bYNPnLKU~M79*eS!OhdX?ARBir(3;l7zR~FkUDuC~!}DKW z?}o)|ESah;W&j|{MbhInj2G=3dXo(2kA>vs>-(O6kaY&Xpu}Vgj;I&bAo#u)RtNOL zNSalsjeb#XPvDZS@aD3_@ zk{8smvGNWf8}D3lCC+~W5b3KVhAG4Z2GJBQz{!#|P8t&gnjX(5(@CC$U@Ki*Eg4B`~T|57q^b2AD zfP(|)Sh`1wR-dkp4$0$xpwDWSZc=f9I3R}*++`{vQ_g=4$c*hVu_!BE9?>N1K<`|z<=nW6{<6%N2pIi5ys;d0yHvjnGFxQ zDODJN!$0L8EM^c_d+xbti)Y&%W<~y2HNNJM1~px)>SK%+yUNPXWP7e`W~i1lE9AJ?MCKz>2n3leRc}wr}`+0)}NUXHLAKNt3jY*ha_XMQZUV@d&C&t4c2M=KE;20sDIKSi? zoa(0T2sAeP9+IpghAS* zm21qiMMnTS7%-DOLwtZiBwnYdZ)cZMf)qR7>H$AdsU|NdZkXfwrF@Xzg0NUddr@LZ%Ksy92fAO{h2UO%|ZBKwz z$Kc2c&B@sO^PZEV$=(}J*4&Ow-m7)(9Zw_f_vRqrKpet$^=E?1#LtM29U|x#ZWr=oSQ08V>IK{?W1_ zG>Ax4&Y(7R$;zwoXw6-m2O*OFog-wyRxTHYRc@eYRlnrj{Bw0UeznK5e34GZyi$vw z(x1@x3;gw^2d^OXDY$$ULHZ+@3xvlo%1M{~Dkw6Kenp*5zLNqRRVqUm;VkIx$|53s z_Yx$ADAE=|whzAilIilU1wDO#DG1lu>r$+cjEIkQBEV;ZPA!^a?(9(RO<#}6am5~rImzb;f0=-5aoCXPZs zg_>gJT0e}S;TOjg#fA8%K>=~V7@E_${B>Zd)GFUB$pADg+nHA`c zP)BNP|3Me^cwwSgR{4a(M$ZfQJF*sLkg1C^r=uPF?m$X%`}L671WmT(NtIf-1!FP+ zbDxmXybrE!CiQw)H)sIH+YAvEbYvhwjE?C`r8H3q^?=;`6YvoUL1o1(zb`Qt$9koE zqmYp#K3&j?mPAupk*-^#X|l-HO~W%}tR#YQ$LeRA^l`}E*?!B_;~-kQ1?EAwfc}t3 z#~B!Ww6Wf5_mViZW%1gj!p$=v1ZD2>Cay<(UI?ZTuh-d?x%rJ*w%a^Yl_dlA8PR$B~T4zMV+ znc~lwq&;xH^b(@hc-rOGx7^&!M_{QG&2Nxadf?NR>=J$3H~OF5Uc%1SQ0&{j5n2mi?4J?BYt{ z(2M@$P4zI&Q~nI_7B1p?kwsSO{MtmWZmBitrFQUSQ5BPks!Pn0OQFhTsTk&T7|tSR z3wvr|1L>Q&mb{S!x|(d>ZXXEASNh2;t9J@a6ZLFh1b-eVEBg!OE03jA42`&tkqA=T zNMfI?29bJKCV`o(DUukj6J|4d)Y{u7r1=WN#yS{&7`l*#Uhg_mURd zaSWVb^5U?3g&2fd@(jQ%Sb=dEiY>*x9td1a^!EScj#8M6Fc=Jyt``13zTN^Vsx|5x zhjG9mBu8l&LKr%wW9XqnKtu_p6hTlB0YMnLyF@w!L3v+Rws*s zI(=Px^Xs6o$FDy2!U<#N!Ls}s`N(hPsNPob_a|}oV7_Qe_tj2o&g*{Y{tYyuwr4jM zzI|PNir4YLmbJ0iWq~i- zY3{VAsy-^n8?NldslUr-;zyJsk#RC#>5sq#q|`-YrQ3H%}SE+0VSFDsRtU-^jBU>9Hm0%D`rZFcJPInmkK*zOM~JeE3@3*dN<)wQsvwd<5&+xq$jz zeC7VoHMUoqI#LcS$g-rYQzpzfn5)glvqcYQ51+{604F>~(UlxVR-X|5EekGss?TGe zFjM7s#j@7~r<_s|-Fqc<)y_o|qaylU<$s^!fikZCMrv6xP((HDb1;!{its*0F4#Pr z#@1FPz|8=BlUOSpwIdtObtX=9f`BedN4$gKk*FsRJiUhFbWiKI*)w;4S|9DEZJx^{ zu=1^Av)&+i9oGIbIITJeyA0j*J1MMklCs56aF#Yds6DxZzk}kcfd_d7&pi0JcTNo$ zTatd<`Mfwf>23OBFszJwONAA}ypf3_3l{SfnLX8cO68XC@XU)={(+~U2T4I0A{P7V z*IM5BX3T)a%eo+K(#6PKvJcQ{nY7nQtS+R-Auej}t;V+aX<9o=rl z&OCMpr|BMbKIHkk^%GYThC$jm_KdpjjUq!U16cE9ymP5jy6x7iUuP}h|GY9~7zM9M zw-mHGy{QF%j0qt7&^JYrQhP@zKdsKoc!*RwV2y-gor#4g>3Im-*LC@u=PO6Rbto4? zHlgKKqNJ&juONttgk6YDYUh6zx06C)Wg9!=dO6vC*6ZA-S7oxZ@?awfQ5l-%{PUvT z%n#2|C@X6zww-X*+?r5(;r@OBUGzQ)zv%Pgo;L(V~L%|ECETAYt#}l*^ ztgE-HoC`i*sV5Z9pr+v9M)>?W7zi9CW^$(LiLFbszVA(YZ~bfFtfb&retx*7GguetJ$huSJ=#N;FZNI4L9G)V*>Mr9_T$L?- zD?egydUt)5?G#y!Z1dA3hYeWT|G4ddX`(V*i12w~42HClwFt=gM{ZPwpS)y zk(9~~iO*^AJ{2n>gQQUtsw9R9&g-uVq#jsD9Ju+njgbxuU;gH{y0*&IYS8u(j6FG7 z4J(_())%<^kMgI)6!ZdaY`!hA<}d`O8X=g1VW$lHpQ&V4#^&j~Pcujg_X!PNox2GJ zt}ggWjq3Z{UnlT4{HPPd+BhiU^Q{kz*{AmHgBc2&b-vmBW$+!q&kT;4SEf04_`JaO z;}5eBsxm*4M@`C*GVGJrfplJ4K*jzgvTydxHdUdN_<0eZ@1lx)>W%`Qr=M-|f-zBU z+?Q5V$Ju5uhOApS_wdXMXE6TcK_*xeuOP2|KPLwa33m3vqFrK%R>d-2fSGWyEnfNC zv9{M3Lp7#?*cn^4Z&8|u7EGPsv>5e$0Co+TcPK@VWlD7SnM)6_`mRsYHB~ZLOJ6rf z_o)1`nQs1)m$1~asBLy%mMp0JwUPCK=OP;OuxB9-zcpr@V=jADDv z4u=Kuf>%>0CELx3x4u~q{bp{wlNYwObufD9s`Ynsxbb;muc>3U~R;*8boxcE41%7>L7Xi=~8*CgOS6K8t># zJepX;S)Yq$okj+3k2tb{TlZjAknC)meD|J&*wvXy&5p;82#)UAjfO|LJ@v-@XWGj& z{0BjI^SDL#@9!8tYWk=P(Rq5vn`<8SYu1!k&fPdGQ0HK8E+jY(j)06TgX7jtvUtRY z5o8#hnRyhJW^N+%g0QMpm1_-=WV4A%bwJ_*me{@2T&`BJQmzkgtp~{z2;7&y*LD!| z_F2zb+s}D$L0IEO4a>e^z0W>5v9MHJd+O_(Lk3u>Lx%tO~UX5Tbp zB&vMFm(4tXXX;a>%j_MFH6KLT2h`D5bD*y$hi&Jk1fjmLukC>(S*U>38}t6h+U55p zWm#Xj@h?tnYwUicW4@*W+UU@PsDjnOwwKr3SiLKo-*9EggSqxqKKab5S*km;BYl!% z0oRyo3BR&l;gD~PED-xVB|~lfY4+8F&Y-#yc~-Qy*DHtQx&0HXGbQBki#_)-16x!m zK{m3Ei&FL@V_RxRTweLiK_}qH0 zHG3{(jm;jqQEhf6FJ3;_Dy|;moUaKoAChA__NI4@jSNP7h_0h?a`m#rdpzA4d0%~Fx-w5R|1_v)ORJoN^Dv}0c zL(81jE?>)rqvdqto@lojwyi4MNSf$izi(S7S|vbtXXdK%Mn}jemx&J}Z!hrWR0S_) zbyk7J+=iTAf zFz*$3D&H#I+j@qhHidHCbJm_ADYL3qMp#Uj;vMnq7|BKnNO{b#FY{uqDveP3NVvz& zT;h2}ubC}6$e<|`Y=h{u_?C2#e^*i=XC!S%Bs`W;6~YxCKoS+ozt=&(u^iaZfMU*dEBYvGU~Ke&c4{5Hi< z>EAYFZU@4RZ~&Z{zGMI1Am|X5-gItA^^WF$8mrJf0b}qFFGLoO{=LOq!VB97wU@WP z2x9s3hqlglI_w^q3;eGp`?bp;q%v)fI{lLk_YT0HOBX(ohk>mWf)#{=|7&SY2@|+n z@ThpH)h zO&7Tm2rk&@98jupf=6C6g=NawJpla^habJ!AWgag{&=QCtLQJ!8A;F~LgRPFJ7ZMO z?|>~4a-}a=1(1{0L4j`wM<3_LbuwW3u>|BJO50n;>}6Zzj)I?Y3M=x)9qI+**f0wf4=rXn453FrpXcW9c5 z@C~zCeZzLod-*HF@y+EkGLOeMu1deE$10ibsXhICSS~#oLzJCF$$LNU>_k$?vVq16 z!GvbDM3AB;YuGH;IQa-xN!)*Yd`V-F1FWX2mX9pE^RmS99|hnXP-}d|-e>!ju{|6L zF=}Ml57t*|8ZUPax4zm;5Yl`smEdK$@k^pGCjN~2W5+RgmJ;#eD%Ka>i}s`?zAbHh zp^zP$!?}*r#O`NN)&08o{*VT(MAtuprHLR^{=XZXzt!2h1DCZ4-$>62m$(!XDknbb zO&O8>6*FXtVOn zcAj4mqp2K6ZyS7}>P+KM27M6Z<|x=XO)xF_!II_<_Fu1Z3c}+Sh}+x5`36{gDxWoR z@(ozkKFqtYwql{`o}qmJD+aO9Ep%D;`5{5jb2)bH>Z% zLPW;^NT&lL+Gry0a6%S_Spk=WF5eqgQvj#1f2dBV!%l-9p5$)|2}LPCvtJzI>a z@v4Q~Sn7!Wxw7-*kI>BUs~yjars(UbKV3lt`bZrjyf`Jpn?HSh?)6ky?P_|wPyG#1 zf>_6DG2(uTJJxDf!(;8=UDGrLb5&v_*zm3|c?!_$m7E4+$2aD*OW6LJFo$6Q9Gz|K z_RaF@(euX#u2}Lh!>Bq5+4f4B4a}T0!_9nt;|zr$-HuYQ@t*Jm)~8D-w2{hU_O!FG z^?cA}_`wmwVha}Ot5ZdFf9{DfUs)`Wsu_6CXZd}{BE5DVJaY`$qJON~-_NZz2!PFS z72d*%C-;tr8HQOkjBA%%`oKqCe2axf-I=s)d7csbB07Ke;S17%S5-27nz3oN28=|5 zN%395!@kyqK6Qr+@|_KiBtg9}&$F2Gr$Jc`PS;_|rN|Znk2@O43~m!4aB(3kIFW|BB`QlAV1U|G zx-@?Zw5$v_1cuFDoV)(*@_(LQ41c8BBCMW2wWWfyMXXyI@K*ZPMjCxOl$orE7n|9*))vla=acyoizn-v=_L4oA zmU0rjtlixF?KuM4F-HyUm@@#6ci;q%A1Qy{@t@1z>NE=xKagR(LWhBB2JZ&rZ!+Q$Au&4JZ)#q2f+QExZ#$>)d~`EzwVd z-L&)TySSCbI`?ZCg#;rV6Rj^%&><-wSX!ZG@BR4Pv4tan=2JLIJ^#i4wcJ+-k2bGz zOumie=|y8M(zX_kKK?YTj*(?%W}Bw*>eJUke7A7~}OsJqab#TP}5BeT5?Yd{|q; zlXZ0UP0HThq^#NHrrF!00RV06Vr60{mzFk)i5a*@f3Q;(-RvCL5Iv}SW|+NJ^YO{q zz>wviSu(OrY92nQkLX9%F=__46;TWU5bd zxn16P{M3;ttXn+AHhNET2bVVf0> zdGP?eXgd~X9P^?F@uGFX<=?e_m@KNPZ#&zZMu>v?#Zs&|yM48vTYx>o1pCczSHphY z?G(RZch7!f)|+c9jzd~~{i?G!(!ugssbfL0R|dVsa=KSfJm&*l<+oq2#HyaN-H4uV z4J@Wnn1Ok21k6jP>M@hO{CH)SppYtd=9Y5>J;f4ObDWC?JVm}PdJXZ^>jaljs%Lb{ z`fu=w!!IxNzriBA&^zNHH6q4}1(lM-5u51dK6If%m|BlzWO(hhj|Jy7QF=K*iEMm;(2=dt9d52pjCjdktVKdk7s?!A!?_k@X3CGYp==WN%cv+cXHyX zX)f-p%+HA1UiZpiD|n_a0O3$SBHv2&2o+e0D(ojh=vyn_x?{GTnAbsUu}`uij_ z>f%1<%Y#g!pT@lQHTC~gqb)a^RCAe)HDO zm%2=?rRrM=9BcYmUug_6QY(yOQ|+;o?I&^{)0Pm46aD+xNt9o>iEiWEO>~7DG5|%3 zqd{Q9(S#X~j}07*@a%sEBRr)4L{AW8&cdR3Mh4121l^;9G zQD@D2Eok|U*Q`_quy~S5`t-4dx2;l--DB38MiYPx1uOy$@A|U{G&cr17vWr!efn=k zRwIe~b?bFh!UECz3tuZ#_#~ELk&i}Iy6kmr>ooJC^W7B~RPA&%c3C41jwm8H_=xa@ zE^*|k(~eDy3dJ(Sq#ZA!vpWmo(d5b!Pj_`<8z=S^dtWv(bJB$r zpu=*PB$)she(-ERX9d8}haG^SReAC*Xioi;1fQizC*0i9%tveVtzPFM#ifXmhC6TT zab=ffJ9EkEDBVGHh z2!;g44_h4p(jC0mEPe^;&;qYB5i4R($P`wfYm9;*>|cAMCUfj&WWc0{Uz-}T{Rb7b z;X~>#_bJ&z%C-}BQKq8~DnYKC2etjDF1%0(B}b)2U7erKw@YI;LKhXUS7DX+73s$W zS_qAsMr#+OJMro(f$O^~ksD$(aiWK73fLTWqvbE_8WKXzJBXZm7fb-FQk4sJJ@17oa7o@;kdVyaZKwLz{-K z{}GP>4B3P}>|;vhU~5GP#B#mka^vxQKyD}*Aams6;z|gkFLHfo?FV{!m-3F<2D|B!3pd|&oc!p4t+~5x~yP#erJw8JzI4t z45@O%raHtjfH`$#a3)+Vk{$1cJjw1Cp_W|`kBo&;+37){@uQW`smlQ5I-ppzPFDCG zJp7;PN)g6ifVagWbDNd(@1kcb-dfP)4hzs-<18k+#M+(lkwWt@VuQBd_oB|=7GZ2w zcHhP$hprHnWnpw%FG(vY?-Ma^5)TYXNI_SW7Ewk3NWr+DcQNJzq_U*x-M^fcrkC}f zl64*}n-!}eHL!O=n@^r#)U@UI972z~0mM{Jy<33F3$$6ZNCaej?C;bnR(H==hheS2gs!gnQA6BS&rL;4|p6+xT zB4}bwf&oz0^L%yg@;{VuyWEwE4M%)5Aw>~bWVHP+lJ|ieuAH|Br9#igpVpirLgoak z3430&C*f)}%8dBxSh37IkbxLr27qwxuGRoML`VdLyWfS!ZxvuzsLYXmjjR!{bz$s0 z`-f02{%8X4gz>zP(-%tNghD==_d9uh)LxQ-mF4k<6qGO<)S8UJ!S;-;O`}y{tQlzm zU+2FzZ85(1t5FuJTpj_s;)lU%dEeO!&nDP~(At>CS|@a%t|zp-e$lSe9RTVl|6r2} z(Tv&I(!muw>BxkIlGjE9OM}KOZ$YrhXZCq~oW2c0$()b#;In^-gOXI;MttBt9pIM< z+mv9}PMs^Fi%VCjnvtgK6uP*Jwp+9Me9jxQcbW&7;xPNI1nr5Jq?&|?XQ3Q`aGp>x zF(-(y7yw67z3l^rfBlUy2>*k=gA}m9l2*~9&b%FON zSSxH=0`Exx-gEOySy|Oz?*V(9NtNX|{cvjR3k+O7G;iN>iogbWpSv1bi9crHtdyu@ zpqQR8&z8IthLLA(H_3da)W7`H-6=~Q&ZiG3w_u_A8pRwPwyU=$f2vpQI= zM4rL}B=SRd5cnXN4g;6s=Cut?nEu8e4nrJ?x;6!c`8vEJH!#9 zmJHphW*1=!y_sq|Z^Z=bYCTJU7OgqgE#xB$q1a!>1oEV%ug0YXfS#TPs9%#T-A?^o zl#%N~@;>+@TjT~O4H0Vx(@Hc~88dFI4>@x4{0r_u<3PO5r+EeWyByXppX%6HW!^;5 zs6GL}`0d&7$Xiapwfz0Z$BVWHIe^_+*bSEdYj<3Tjn{``SfuEr@+gfKVA8LT`PYQ; zh{K>oAYT6y&%70?%Z=9(aDR(HKN6(z#C#V|UnTF5}tSu-XHSqK$Z zNWnFxL)jZ(AG;b7+Q$yH`)Z-AL$F^q?jM#hAF0z>I2BJ{C#6xJk&CB)Xl}*=8_vCW zd*Z3=hq6I9&bG>6VnZl(kOBuBP`vkCw>sD;dlvBPwCGeK3^BaM1MI^8S?}>?@ZW%K z5{=)wwn)oGdR>^~X%JT#E1^(jhxF6vUjjE+U@UGKTG*cY?nRGO4w5IhAM0+&u`?H~ z+tqV30IMcR<)aW3ROV;)8t22f0K#2@Wb4CaRaS~6*X&~j z-shqYeB@HXu=jDoAO&Rc;@84|8l7Lb@F9&97*JDR1=BtJs5cg2__xxhLMqbYAGv0o zUlJgJsa72^^(O+fA7Uj8Euar-d*Q^9_}Yjd@QEH2MQE30OCf!IIh*@SMwsJ2i|uh9 zFyHa}%rxq0+wr@AavXtmnWOLJ$Yje)t2MIc12G26KjqwvfF;*z1x!BlNBPCHeR~AC z$c;Ndg%&I?^wChxM??*RAQkuN|1_7BNP69W+~kTBNQ&R({1C`>!xE-B>(NN;8)G$8 z2e*2)=#R;$c6pgsO{Z+5nB2q)a@@#(NBO5A2f2zKJYMf@k__BBa>m3KGLz$9F}gOA zM^!Ry{mPOSOQ;wh<*DRupr_QV(p$NE zQNfu2Fw8i`;e-H`PH6$3R<$xarTtG&Dz_hWheRInv{zn8ki;a`vf!qr&sDUCx(pL# z$!OScJNrj&C?;N2KcSL!5uv$$YWKtHASd>6i6J*^5Q6-F+&CF(>3Q#)fQ|LXePmFT zlRODrSBOBV4ZCoBiC#npS^>&0{GQzTndHt-oT9eQtmR@{x~yt6O*a z@7}3yhT?R^x1tFsPE!KA_~8EZoblf{&4KX1jQDdNC<=>D-hlDspuZB zv+Nt8g`>s91m1~5R>20W!izfM^^qEIY6AF0b&#Hwp!Lrkr-i4X==YDrA@{>@Qsvf* zD46kT7<1)Gi8e*r*D6oxdjt&^xw?30Hesor!}b~#zd_dQ4_UJzs4)Ylt&p+#hvl|U zx6D=4o?0<%Lf1S;pjfgchnf9b#f2lB0|YzR9`&jVH;gCP)vDU?dxQ*sts7lT^hrcj z%5NQE8aRROcF$rA)|ukHEQ?WDvB#Lq9|e-GXKSU$LE0n+7{=o~)7HO+v8iGs>XEF1 zQ17yi?^e$^rDY}u|BAVQp70N=aa-}wQP5%+A@^=!zoRYl=*jNc$}jd7 z-kvv7QocLamsxOV5|7e+&plR%lkY;ZGU~GNkwNdhX z!&U*0G{>&;19uDojOtnr!PW~u2WCP-1oUG7hLA+JLh?v$H+GpN3P|>|_yJ8pki5%EFADx(zelYOrXn$?4Mb9Gd;CvFDOO z+eKU=Q9gGvlHHI+jg6M8$k_05&LS0vJxlfgzwe|Pd^kXn05FV-gPR!_9P-vyFOe+P z8DITOszTUCamZA-s+}f?xp#dg7%p#nB)E8o)*-?8Dy;6MD04ffPt*N~J?&vxo&e5# zcTZ*#Kqog1UfI)Bs55@dE1*msjAxep7GW$G-l-Lr`m8h+g~T#Dy&mq#48 ziyR}em>?unS{PB^%^#SYeODM@1SSSfPU!_R*6SFQfrFl+}QA~r&lF& z%!a9+o2)iPdv_m-1~Gsn)HDQy`JE}+l;Hc?V6&B55mP6?ERpF-H=ob1dNSN)^1 zULshwsBhH(1)_&*i`XLjVl*-de__zs`W=e z;`x4tsIgNPR;o4}O)WZ0UbW|kzpQ)iAiR=VKNigv%|a3mW=Aqpt9tbir*GXfJ5TqzHLqxc}gpAj%zt}iW>XEzC9*u zE}uuX@Nb}k@JQ`@W6C#j7z+LHwBg|BOYbi7lU%0dx+n-kGDPqZK3G#&~{Q6RC z#j51o(wU}Gc9EA8a@j0kAe-oM~fJndo}mW6q%hp&3X zQZY1q@7e9UDHDTKJ5MI|Uf##*$-1%|#sR%A^TkY~g@ypQ4iuP1doWYCKi99Jfl<*b z0ufBV{JKH^2LqX4R-xZN)p#;02p`l9P!JY=hI5;3m!~!JTb6&eEV|18XO7xsEp7Q} zr4@k5HHB4|qNdRnMJcPdr8$21`CVfH7}5x=wDsP~qRemCx3Pgc3_XZT^`RA)BQr?s z=28z03UDOeoyHr47QEaL3&Kk!f9=8RGk9|;=Q7|%-H_kT$p!3xrp8kzywp(%f`AGR z`{byI_y_tnVgek={4JLr1bfmPm^LIM8CYRIOUf#=*^r#$>}?iXzYRRrlMP$LDEKA>Q-CU3Ds8MDPa86z${Ihqj{~ z@?2+`Lr`DL-PFG9%=AhiFg7J5HaTItKR$Z@L6230ZrgX%U51p`4*{orY~7he5T`G}>#xuh z$p3@QdL&-lX^tKvgkN5D6c={6(e6BLSnX-mXpO;53{#nFtRB3OehN7g{VBq*f}NOw z9KqK{(V=#$vF+4-a&-g1>oGPGfM`KpXVpJiibhpFpRi=#{P0VsU!f>TJ7Jo;G8T|+ z3ppmszD8FRm(*<*(X>pIe6xi=&=HLR1C!T~JgemUKtvojs- z4keBeR>!%mm6N1@F{$$s!Xpa5{20v=dsV4v{^yWj!^&_FXa1l3B$o|PKFED9a~%8$ zU}w21pY3i4mu3YRVCxg~xztfqBu{ebR<$ZpevE{h?BuB1Xr3KSbWsiJ}cRFfM~O_$!PhLB^p?xY0R&KI{D?Q5;lEi5sVJYfKM^#PGU z3F%G*a2+(=eesV&gm8+yuvljLcA?0V##+eIJQ9P7!sE0z=IvIW==P()7oBX1eu=k| z_mE3-Z3Y8;$>iOf|E^csYNX4q?qdKnxXR#849PYN(x6I=?H_TdYD|4xs;~{;b=Xzv z@6o143~*MKh{-2?5|312JbF5uCw{^9YrL6+Ho#NvF{M`r6EQuG5V0rjSG?E%oqdG-?x~}OLR_>(H z8JHz%$_@Ea%Q|&e+$#@cZ-Kp>uc-StD^18CDI^2h1@NxvKS4%}CfzJ+H*dpb(QDDQ z$Q?*ng0r%k^wXQ$Ue$qLfPC?tDPMbfc#naL4er!xG)219|O~QQTfg9Fdhtw?*}y zg_V`EhV`twP6rvQ2$87J5oxN?T`@il*{~3lzfyCX{>fh>b!}wM9TJziM&_h`N7c>( zX_mnoO~!I^?pP=U+@|V6tq~Rda^DDwmQO_W8o+`J7Fb-EshezdK0xoQp-QkP&*;Mp z2?7c@gt&`?VY5XPqSG;ju_^k(>Zo1{oN!rX*1h5ycPe}Kcx9WbMG7cCjkk$Mz`8cG z0#t=%;7Kl@9~!?lLcB&3X||yWZ%adrvQpy}w-Ew^fAWDJ`grl8X5JX4?aSrEQFBdw zHNt6d2jen%vhmoa2ks*(jHVK>N#mfEQ$q`w*RF9a*CZtoB|b8lshJ4LLE#2k$>dCWERB7+pJA>Uz^U zO_ms~^OA^gF&#fD+n-Y$C0mX=!5*(SWq5Y4dh@}uvoX7fA&@OS%YA0*g4xc#V?NaZ zpZw3jOu(^hyQp!cgQ*8au39TzG8bg)0gPQk=oSSja2}X0$`_P|+XCt0b9g)TS_Gg> z<4XvB$tm2id9QwO8aBuL!@>Asn3*eGf(^`B|-pW z8)8+r^#dHrU@1zR~gvv+^YY!i<1QA&1uLKd)4|}{F?sA z1rkj)NjhT)O~^Aq9ngCr;OC#5y+PN;VQ~BW;yq)zANP5)v?4LNm*Cvz)$6r7wH_>v z2tFP-ABV4f>vdjMrwLZ5igJVx8QudK+}>t}8GNGf)&9)<4Qg&)_0IA3bK zQD((Aa)z0@)pv7I4iqtt0BPi{Swd>Dxx+@5!FNf9QgAVZZgEXoQEW^MCbtAavdoIu_ZJ4b zqo0jSb7+vnw?eAi2nUJ1rcLRYKeomX%el}_sk2h~lk%4ZFpnl~ku-f9&2i5D>pp&B zOJNvd9A~n_%X&`@RxK(t4V2mKm8`d(iG^vZB`8+aoCf(PH(>fo!{`S1GcZ9?JsXnR zL+w(Qv%=bU(|kN>V7U8KYZ|(T%cu5kFW#^G$~*%9dj7}D{;29|tq{yK;z{Y5z0l8f zcRsx~nhHmM?o1&DW~QnFe1eNET1N+P$KRD)P(`sw=&5FBgDKsP%2F1w%p8&<4s# z}9q_sU-cei892imcr&MzAC$>yfB>BpdS^6_GoOM!@!03mfzRRT0zUrnxqi5O z!2+_B#eKGLqA?<-6;8;2AaqS$=$R=xAtT2Vf|11OB`^2PHIIxGs^qSL`unQEbx_wg zhO7>DQA~x?zX`evary%YHZzT1S?-uqkeuq4PpopsNQI;=ZmOv21$R?s;FF#3C;EpA z?cEK@GX&?^SO{HbeuWQ|2|CMBBa&0_mzT@|;q8t4x>~YPocUaIi8q0<7IA{|Zv1SK zD)bbTp#&_)D5$A%K>W-1l+-&9N*h9v;rIlnGNq(R0mFyam)5A(g3kFX9=Uoo=o*Bj z<9PgiHPQc*d5 zs(2i&xtXBX1)rdShkP7VT}-&eK~x3)`B~Rf1qxIP)R4u_FUkMhTDW{raz;~43GIFy z$5&|aiuFCwoPQKnz#;N9_OR+WPk7KjQiOp2z~JBQuK50(cYh-<5iW_zrN9-Wd_U=u z?Gk~pF^8($)uO}Yd*?gzLksZKc~N1&ed_`(3ds(i*6E9vE4fsH-*$S+xKY_gsXq%c3HoaLe{va(_>1 z1UVDP_CM(?i3qS-BYByLViA@iaA5lw3Q(4~dl_A$IfmZkFue29TM}bAv5AC3-K9?% zKmZzeN}=-9-Rg!&fWy=XUzM1epylTr5~-3Zxtj2=#!aBj_04C+4e34k69nEkMe_e= z3MK%{p8F{XvUoXBp)?_GbyWNXm|V$~!zZjs!^HhUz;&lY6f3kGpClQG!9zpv7E24` z#$&g`3d}V#F1(^n80J@f2{Mo?pnbr)Wk7HMb$dWrLF@Jz?^UoBVCDLGQ{0dp-k@Wn zZ@Qhh(PHdc7mmrr!X+=*uF#LY#Kt^&3fTdD>}yJc{U&KmS%bLla~V#z)S^RKJ0W;k zU;#>7{bVeDED3T3Lf0oAxB)4L3LVOLnt4;I_|LS`27(*&o=uM`dZOh5FG?Mo6l?h0tK-H|W9{r0>xDToZa5rvaLT@yfE zKktWJV>@Q@O9nn|K(@!OI%vjh@iD+{b#{>;#@)gV@5LwT*CkehF~o$OJYWHiKWOj3 zf$XLpY)z(oh4deO<;bMpA2gyW01|pPiPexDBjIhmsRF0*$wE**^K5q9q1B;AAS3W^ zoCK;xqCDEK-Qa{N?M?k`^eIsJqHGgR^5vKm`ys0T4j?rQNWEy5m-yY&`k`UtaIUL6 zd>iyf4dOws078Qsk6(d0#HuFrqZQD2Wo5t1!y`iotT9u5090?q4YUw$Ybyz^)K7&k zNZsl_38e$)fE0(MjYy9<49&!IEgfz3(-k&XHE8cr17PK#NjHvZHrQ?OIOOmQkW|g3 zAe4((5wNP%S9}AC_dWPC(DE;db8}PMpq4C#e6p7q=$fe#O?s@CRxP}^uxr|=@_x7n z8AOj(`f|+ny!SlE-M~7iI9SsD={Ux(Ls|GmPYAc~OCWH(z8&pTz zaQ>9vfrdww+o(XG&`9v!L_OD4Tsrtx>d_=JRW#>jss}* z27Jh@>OKS@eWQ2skPyB50GPHPO3w!!oB3zjN^vi?MJ8jp2;ul{9w15&m?!yI#8#b0 zY5v{NE%3@X!IYb0O^#WnH_u!WK?~Tta$liMC&}D9PbV68IMq+&1%T zGR8+%pRRw7IwpGN|3UNsG~4yPiw30BLFiAKu>p;03HTXf19_bZov6;_M;AQcuo3u- zYQhI7^b^1>Q1KL+(~}e}tEoWgXS9|en!T2Q(eFPBC4bj2^n{(2^2WR68w!hW`Y#qD z;BPgigqM1~79ZPxqd&lb{NzE(*OQ!5ke!1HTOZ_v`%^_@kSo^QKZQPSyXQcqK;efM zzhj6L=!WSubNiVsU2GfHQUZWvr~w-*J%5;a)EJ#rU;whNDe0m;_ZIEnA{~NSFrRe7 zMk79#0ydMGJE3ZAK@b>{>n~%FwSlziOME~U@kH-Cir~(oOTcwNlw4j)Z!MMQ&MJSB zRcH+XeR#io)Zu3+=o8?&5xy2-Q0UXIIqR)I9za*c;g(LEDa&`JEAe3C3S` z>MS*${2ZOc%AKVF@{{-QnNYQFX)lsCPQmUVE|++Ooyll9ws*`P)FvIiQ_^YDlGZ)$ za1PW3aE)7#9Q`=Ji3aU8{oh^EAkL|nms{~2J3eU(wNhIuC__&eQ)y6h#F5L0oc0mQ zFbvO=@_iNGcjt#zC;?oSM|!sUFxHVNl;Wc%aDBIj{niOIK1CF$M0OEvDEqlv zR&EAGJo>X96cD)gasmrr#T8i`TL8TPVdtZb_gCb?S5Q0UHG>z0_<$7F;QGdt`@fE~ zr|+qpM2X14j*43kEI+w;47y1G3IU*>;R|qKV6xr;G6e(;z-kOC3>bn;BU*yw7*J$+ zrWkC)u#=#xSs-3G@tzEa7oj${%-WnkioCKU;THmM+0#bhte?4T1QM90k0yxEudAcJ zk;I1k*kK`7Ma%)KuYSxgA16Ja)Tb@Y7A*24_Tql0*MAyVYiJA}xwPhASfN8lU)TN7 z8p6Jc{)4eft>4D=oyN^~O<1yoMpNyCv>jwv^eDpRp9ItHPRDP*K!KYx{Sad;N0^;@ zlLzVu;6-S5B4k%qUzfLj^4=u}r9}tdf!^ZgZ(Z%`fJp4`?SAY%PeFH~UOV#kF>~>9 zpwX+&qutatk;fgI@a$p&3Z<%JbA5B4Wl^a}po(oYj*z87bqZdz$No0*4>hQuJ~DUb zhIm;4Kv%CC_3Sq_GT21&O*#AgPa(Tg++aP$|m5G zBnZ+CphRZspt+tAD775`nPRzSsK@aOcAdo;l$vg1S5Wsc4GEB#6YUI?*S2TE@F0&| zqIqsEv#Q-ReFo@{JeD9f{8iQbdx!%@(2$VIS7rU}exdk4r#D2#a<8qDzVonfssk6> zmU?>664e-yB~`5oesqT2;2&w>)UAmK zFtIGdS^D4FBg5%=q;`U!I>}*a3Q^)DaW1GojAd35djQgLU|`ng8(PFC%c0x{)q4+A zus%KM;@~e*Ed&D~pmk#Y?Xn7IE2Eu`9u7$T=+U~Hs4oD$VFKLY;}~6GoK7*@gLXN< zIt5{vqqoJ9^!9$;08UK|?xUOgfb%L_)+7_1!RV}~A=EY{L_~A-zE_MB_yGO|cuW9> zk|f%6yiG2)E@1geg-TA2BR^g)q$a3h@yS+H) zGlq2fosS`L4qGy&$!W*dL4cb8M|FeWQJe3vlh3Ws9)v@RU7|I&zIfOyeNzf3vqsa# z?DXB`y&Ge4(fxpnG=zk^npf)#8+I~&xBk1tA~VQpAY#zd{JyV@l(HQE7@CdG;Bb36 zAVnC5l}h3O|I!xrk#}tUrFC-m#B=nEW1;f!j<+bhJ1(|Cc84=#q5fG)LZ@|L>8GwO zO{$E6#IO;MDcgDxrkDHM(dac`KOcW|)KXa6c1~c^E(TqK0E|0~rzE^Z&f3K)8FXrZ zwsiQ$CkrNrpei0B?8!o%V|xC3+OFI;65=u~>fcIN#Cfi`Z(jlzV*&dp5fk__`NRdr zG@3)@ig^}3n8z7d0cYi73O3<`cMFfFuOToPxKL6vXBHD9c!o8J$4q$mG0Ngfd`}lp}`oQEpKdZuio!xND{g}->e)6+LJ5HIcD`6+&9TLZh+F_jMIULHbCP$ z2w#oGLp|A=-?70J5#2#8+LGasFfciuRwSpx0~+MV{Q1BNs(K2PT>vaz5m)5VHP-*I zNdDUO95zi%E-TI@<%;IV`lZt-pzsA*+)WvdM~3ex5<9>=#L~Hkjh+X$jljWzh#I`X zJ|_&pUVBzZ0kj1;R3_4yVR&n(elkP#Icqr2_1k+ z2((!>ZKPPfuMWH_C<`qBIhQQ_ey)dqr)0@*C$@w&-Bx>2>;M=(8u~WaFy`z8<#L8T zu%>4{MJF{+9^;G+7w*NzmPDy*&19mFZSHl5VGzc$&u%shRI@1jqy`UaFu>~!c4{4s z9y~6k24Y9`>S)5J(P9BmN`}c*hc(so2uk9v9_!K24rV*B(^OcYwZhemZODZ$`~(=wE#krh3gwNwA={RetaSvoY*8_l$fb&r_sz|ne<1Njo~JsT1igCC@s75 zzUt#W))|&&Rno6zKx$|kt8@&j->E-YnEu+^eD~c{OYgT&@Q+W{i!XuFg%IHphf!hy zo95PY2PR!X1$T^j;BQId?vKtdpNapSc87oi0}J2MffL^^6lNRAKR9L;;DPC8tgtg4H`5H^?t10o)gFYb4(uS zfDOrRRl4SP>aZlGE7ze=R11W-$x?l#=#i3>cg~*$d9WUy-+sTzcDBn|5j09J!HMU> z%`q&`)s|L&y)zCgNLPdK@3?p%w$GV{PF4tDpngjj-95c{-k9=L1Pn|`HgPkzFI4bCE;fe}xwdzi zA`&`d4!}f^d}4R*tjsd=M1sRmrt9Fn7Ea-=o30dqvvvXh)l;@kAs9~B82`r>Z#fA* zH4yJa_+Z{{YM}o>S>&pHkabk+A;}A6Hy{9id8J4x?!QX`enQp5nT=<-N>z2G2ilB` z!?FSB;U;LL^#}Jt2Py5LislIZ=g=noWWm9F4?|cGCYzZWBxLuod;f>8uMVhs+tyV? z0fP__kOl>$5u{6zZj|nBknR$tS(Jb@k^<7*NQiW|uxMCxcf9$-v+q0S-Fx33dvA2F zHJLHym}7k7oAZ-?F-POKU?;`|>>CYjv4dZBoLk{0eooy+u6r?EpwMnvTH2W~%0PQF z8Q3bq**h(9d6}Hwk#GAnd81y4tsGjXwltA}K^~(m4q(X>!sfB3x7lAok>YPYAKuB8 zKSJp~knMI#=vX>zkmOjywqvbmp!TjXziMPxORhaHdT_k*1uA%c7i!Ygu8Uu0`g;b6 zh>{h;0>IQVIP@*dy#t&L{OR&#;7e0gkoU||f`ubSq2EKp>2r7FNbw)cGr1z<^7ziTO*_4NyLOCOOD2^)`nO$Qy) zd;GiBgON&6?WVRshMc9uQy(ar_{t_mt4}e!Vn_=0OJGyvT8J^z3~f@G6mdEeCJnPs zSk9*7<0Q3N{(gJZ#b`l!BCPcXvqB0}AE$0;JYcbDUiqYruPA6Eb3+L)$e7rN#7Sda zXWdG__!I*3#lPhf=+Jw^G$L*~u8{F*8q)VxSBh`SM7bT?76 zG4|OxVuS;7o_t8c_HRM$&TT9O+Km^FY0^A;nWWVqXqv1Y`B$!GyCjGimgkEH2_RR_ z%!#zWHVk`kR88tG|{bg0)EZ#INE~fQAL}erU z5U_WVP-FGi!t$|c5-2}@z{%HkgAVFbDmnJ^MC-{LMv!0_+BiX7%5bkPyg!+`d7=38VCo6$(bt$;SpEWe~0ge+_@UC!+Fs@SP5$C5IqdCDaih{;p?+F@O4U>#&$$h?#T@Sz8LV{B?rf=`A?x`VmWc>7riSwDr( zOCE|Rk9~tPukxM7pMqK-5-=AWKf$<7J6%SkN6?82SZ1UHKb6J#@I7AF1b-Pffky6+ zoF$)dA-H0Q(BQHlg+Ndc^U0`QL-INcN0@Z@pHX>k8gK-hB_#O3zA(UQz>Kft?o&+3h%)+)KG8E1^;pkv6L7Y`Rs=P zlmanj%US?%Ec<=;o`Ze$^D(~CIj_oEA{5>V0?u03!9!39cVr``NK%6a-$wQ!H6F3O zJ=12wm=DU)Pcg?;U9R}8hf*J^f^X;}wQK}@l`!$7Km6)hcc84$JaMyHiyxbqr&csH zZaswvaj957ES(nx2d{FhC9a=o%H1?fUQ`v&E#sPCUoy{@5CbgH0aYsRAU4Bk_$IzJ zfmj@o^z>4n(oL>ZzafK()&|+`)!woNlyNgw-;eOzg$5zfxV44*;I z4WeW=+XNz@`RI>m#_m6!I{&a*o8}NI137mzume42xoE0tuicV145Dd~X?F_CP z`YAW4^PPs~%cjn*(#d53QkhGQdFYEa; z$EQ;d!Pu~oV6U&T>@A{f4S*Y>1jS_h4$5^+OU|IE_a-qvK4w4x(JBRisQzIZD4}&1 ze597FHy8og{}=89WN1gHGe zt!28a5P+$D0D=88^f!27{{vtPT5_2(&_-}Tb$(Yfolz*}p^tbCr+_jy8Vn!SVO+09 zju*1At7tbqTi>6b{xCPS<0kNb3ML}oMj|%%k?7nGbl}|bu>#1aQv%H))OX;IH8bIK z<#!OChwBqf3=%4lH{MM#lj4V_#n{&j2qEYH?OG= z_OV)TQt5!nhM=dn$ZJp?UVd(ow_t+kT_C7wf@oc$q2c!-qcFh!D$*ekc^24+Vq+|^ z0`OFCK`u0+bgR?at#KddaMVDCDL7qTYMWQpNL!Qlvw+bPrxV)D#vW|R=WO;h{u2-2 z;{x>O`;HAWG$9s9>NKY|IVhGKlFAWKn=XKNR8UV{uf#3yQY+pEKEjQ>tb7J)sek=e z2%uZ)JqsJC%LAuj8Z9AD{CzG^>BTn#YxS++!kz>e1v`jJn%5zmpU#lrD;Nq5*KKPB zm)Zjcgx>RQx@nNBtYLGCs=^3r#4afo!RnGiw6n{wk6;oQ4?R%lXlnXmpOQ1vgNbdi z%|uXx#dwEQ`u#{-j4!>PH3;0nxxo;YsEbl+Ruf7*y5Negz!S2O6_xB+Jb+ot`O)8? z{s8MZ7C(v1l>v<2Txwu5-hk~=)R!NbMg)!iAyO3WruraWW&>B9LQTfs#c4`g%QAlK zCQ@wt1Ok~pU{}dcdkJyxf6z}o#x#Lw(eK`-)6PC}^rAS_dZC37{G0Ck!~kcY-u#vv zvR3TJJASX6AjC;!E&CW+9Y9wO9%l)xkMy44Zn2w2ya4dh`1?2#JoiF*@;%TOWB{u1 zBcp#7;taYfTBZkZIoMjN1>EB?7iv!lV5VWCRauqT<$kD7q_KzkJ)t>lA=?IDx>sh$#nG0H<*0 zxsLJ9?Lm%AM|78=c$b?5(H(hNDONiI?4v!In+bbXRIBBjSfnU5D*(oE8<-U~8Nvl= zj>Z-C6e4E^nb zW+QF=zv7BFtAV#YQNe!dQwY;fj`bAcE{4{COb3ZG=#=Qjs|wCicGgO)`3yf8Ov;Rc z!Z{shG>fc)DXK*FI@DD_9_|0sBpYqbQ!D~`DjgNbQC&nkaRyyWSmpuF@yYt@2V~)R zz&z_T&?do2wHVYSW!BRNDo6G5BWQ!gH*)1UHx&^4m zfX{oa9`2o5P(jobSHK$hBUJSs zu}^Q>MZ4X8=`PK!e>0uq&>^*r+jn2|byfa_7L(e&fA^uE$(cnME|Z5jJ~%$+fz2ZQ z?I(i|WwZ{@ZqMYy87P1?5!89GG~u{0a??=}sH0vZ;BdO1V>!M*xS4@IH2-&$L^)PEt&pnn4$J%^}LSr7e7OKwV}br6@( zh9B)yI!$kRS|;WyRD$E6Q9uEQ0zOi3PG+n)*ovw(310{~AZX4<3aJ7Eq7vct(Z8mE zJi#yIhCGWf9^P6g8lHhJRH&qUG9CUSlxZ#5E-4%S*VTUs2YcreUNj@<0QTdrTH>N& z@Cerrc0vEjk3kIN@x>IS?<(|u#7(4m8rHP=GFfw=}nNKT5NQ}LY)!e)7#{mB6{ z)G|Ol_(S`m6Eyev8FPdhAa)HY@VHrpm$*Th8N?M1{{D%h>OjYIFDvr}I0gh$`F-@G zmu!CLLa~X@Hww_x@mNrcB2s8~?7{dMbAwlM0aw&zLyWi!vXs|4!kN?04sR`sBSsZ? zU^n?t59+v*2Bn8=jY4Vj;>{Yp(a~LU6CQGr?u>Zkqe~82JyD(n<{rgO^toN~Z^Zwc z3@p)4;fx2sD~chNu5T7*HjwW(Eqy@P|6TYz@ewwX*ZYQ~7Z2E8 zh_WO5`2awCPs7kZy-H!tX2@>PGSlLU4iy#oK19Iie;`_V0|Ypmo@@;&XOMi?pg0_~ zx$!{Y)|G;;wIc}WN+DDM1T$nsezdzMi(hZ(YBZc+C*5uICg_1nnX(XlR(4>FmG^sg z6Dxy@5RD>bn7|5snrdk63Wqs#jwQ!pZ;XnY9K0E6puRUDgT8zNrawaclUApkIb(q5 z)5Hwir+jaoHh>iH)|R`MHfZZV3YvlgS<=lEfe+5`rZ;QLpA~o<+!x9#?Qdd!vVJrl zCIs136x`mHx&6j_z0sjtn)>B@7YEd-pj$70l);^frG|!sfKtG@(Wj>$H9zl_8 z7f*j@+&g#_0|VA@NyeNmv-f3q_s|H@j>ZM-nAskgh-w`zM`%il+rB=#1@nXyjQUz% zepwk{VO7J&=HNdzQ2w}>0B-BR$NWb@JFk$b2G1EXZJKtO>a{Yn9$G{3ul<`@1L8$O zf+_r)*)2rfNDs0!XWtw_`;Lcn7X-U$xA1Z#r4Nu(TEJZVA#?>)94Tmp|DE&p5|uu$ zY(1l)+EuA0=?k#~2%wt1T9o38mHC@;UM8tJW4#IOlSs%V>wFg zg6R&K6v8U&T+P*UsBc3!X#>R4bKo-pVHdF2Cz+QDYt;SQVqUaKuc43^>}a1CiX9MT zXx}mY%^GkC!0&q-4^OC;*g}pf^#_Qez8rS4Z;vh0K34Xh`3~*{ne>J{#$1JndIF|) zj9~9DAi<_9OAmx|tg{NfFp}Ry+xAgSy1Cu#MzK~(5}J^&d5Wp>-en=vm;=iEI;DVT zi7T|)Z;;NT0F`8M!Q_Ybbr2;OpOJO*9)jjqd(*?S#L4@_ZzR1$CYmTNM@+`S;j;4X}Z|L`L z1v)?l*?)o1$U%7kgI6{VcQxN^;AyH^#RrvQ_0^q`(*=oVP=Lrrj;WtcI*~y%fk{IN znl`Mz=>_$F^~a)K*+OM zVoNW^!+VS~OGkKvaZtbl$Pt+1O4Pg3?Zuaz1S@~-tjV*pQhKsVoU4Q!T+QXA=(K<3 zHWvHi0}kuamOXT<0Wcop!T@U2&w-TuqSSYoXY$N%^(jL1UoB#N6{2<(Khw^!=D%@Y zzEsS?PiN&g#~#&?Cz2w0K+_ObB>90BxJI=#H!;Ab5?RC51KsKO0CCF}Yo-WrX1+~k z619qJq)t30b)^hYR+|b(?j1q1^dDV64&;JZI{?s@d7o@Kw09G=yaZQc2xj0KUl2LqVVXBHrmI zFUxMoeIJuTwy z;IQd@p?51p}hu$9GwKeMYZGHguA64!nSX9V%-kE5ewI!CCLIUk$QvN9QV9HL9!I& z`$n;ptrQb0WfuU9GV0zj&HNTKgve-32tohcv$AYH*gKB_hhw zrFnMEH6N0M^;OY7G`fM>LxNk&6wcK}wnU1A@0VS0Vpk>8f%WWZiPi)qAi4nH1-l~#x=UICW{C~!g*pwkO<5lyw-Xip7mZR}hdJiaAN%c>?$ofj5s^fDvGR%FE zvICM^eeGHQX(ic>k!$V~_M0Q1#FcDOHRpF2U4z~dY7Hk@qDvV)+pI!+3&DS zy+PMd`ek9&e9$6z&fiR7?Q#Q1=Wqh)14}hpN%EVtCDHQ?(V=c#k9&*0W;LxNH?M%Z zju}c}pd=d-ELbE3vO~z#B-TA#D~TO%9x!~NuiI(HUW|gK7F?s_3{rnC%yqNcG;BW8 zj#CUSXNc_eBV9iNBQYQp)o1|Ze)83+l6E&r`>4*hYOTd4!C-2)X!wD2Ya|><7Ja)4 zWuN@MM#H~VwGc_2>`YPY%aaWMycUgtYk%4Yo)=F^beeHt7~w`_M9tG!1>$^$Zt7Vz zULGydX`f2qdJ_{L16k!mzMGrDP*4jgB<|I3dlZtx!n`gPI{JY4n89aUB@-1`_b=qF z>Xqch5Y}GQ&-~{TeN;dO)OO*{@6UqbsIxST9iKA@Zx#%cC7FOg+FsJOJ9Qk;EQsm> zl9%?;hdZl43Xx^k;&Gp+3{Q}ovqUZ+3qe?b)^0=$ctKjA8j+O{36$vgle*1s<^{xg z0@tT~2Akz$G6gkjxduR0&2kPk$N;PAc*ZS?^m0{{yo>Jq1CFsgMSckK2b|d5+=}sR zWi6NI)fanR*nRUSK!qlOzG7Uj<7F2;wx^U)qRp=-=HJGHnHs)A8b%DhDnNfWGR*TJ zogp@x?8Zq$T2L(yrzJ8UTg(D6orDX7tk->N?$uOZHCr67lNM4LU?p)MfB>+5&5Rh& zCqBZ~mqSvlukstG_oV48qell&;j1w zj^@5fp`^?Bp9^6+vyc#x zO)FLhkW_q}*bl2WrCwvK-FUnQ2$R+8hSod0#A>sn67BaT0q zGo+5=x*c6ijfod)%8mDRsS{VvHWD?>ax$AEHz)U^q}f&XHm$vQh^$2`!lZdDr)30a z%1*MHVb;M5oIKl;=7rKE?mItQi{I4S50vI-0})cWUo1O=w);IC%J3SDWz$`u-`k$Y zwR7c3(~iv9ODF;-ujeP8#sJwXw%u~hS?@c|uXeg0RkqA=K)Q6ZUn+-8Qap~(N*jg_ z%LbS2U9>=AbxOWd*?7q?e!tSBw1-{t3W$o`<2k5>UosXaB^pGEi?FdzGEO}eSUd-- zL2S{A*Rb>1AoSI!*wcwkm59x~Hau;jjlTEqq@&0E)W?A9Xx-*1)-1NVf|9mXyxU=2 z^IyBK`Haqov-zXD!JY|J?sQ2+6el0g1?;V+hfyWt%#E0m?0c>Xk={Q=ABcH%4&;bQ zWzYpKcI0OC;lL=V!7J|$kGE4IW~L}%aQ9^GtG(C`APzt*8)s2IqSOHn;FfBO7KST$ z=x)innFGi`QFgu+ zOSC{P3!4jK7wq5-vwBJE%B+-6dHJUFc3wM8vh6ELj=Q+i-tYIz66@lRfncIiR-$cZ zIHY%}q%m4DA4KQJ#8`iX0DaLx;8`Zl<(S?GX(`}dk}M( zyb)dk-rmk6eV$h~eA^ZXV~dt!)U7i5e4H@!Ao_^Y!Qal#aVcOk^caT**Jn)Ii?7=# zIO*(SMS#?($0er|=*fovCU{(O(b^|FOhk!pD%DiFbHT=z?-@kcCQCZx;&}#Tf2S0) zhJDGQIuSxZ>P9QuMJa)!a6jbF!3NsO2=-XEzof2%-#z{jz2xYPeHTYz*CoFeT@4@v zIAUAQ#8xE(<3C$vULSQyF5WoSzFbo_4_1PEopxy#G#o8c%k%p7Nj_$n3Fss2Rpp)H zvLajJv`F5>GFEaH2}&IJrjh5>-NlNW?mQ}j)7Kp%L{;YycVJ;m&40QWMb0}&&A%IH zu%2I8a5Och+fMBCu(VOLV9L@l2@2jxkz7p_AHkO%36B9)Ni0I&(O--*m7S$a^WAKH zNJq3mWd;+QC?w8gyHbW-A0IH{E7>|{C2Ff%5EeFGo#}*emur5bxPoFkkP!CK!{!NE zpPb*Wd(*3n%|LR^)j9!$n!~}p%KqX%Dh><%TK@#&e34o}m0|yK+e?7T|2m9!PfS<YRj6tU=l21 z(#zG9?$wk4N#*xbtJx7R7je08a}5^*&`LKn!uqn8#&Dee85M24^LpYambh7*g!M*#T%*|G>667~(ESx~rQ@0#%uC)1)r1i7?wY-U+ znXBul=;%Y;*yCfkgPWhIT1lsQwN9I*)2X78YNpzsqj6KE&y}c%iXoOBM^=XWr*b_* zp|82=>Iyj0$Kxv0i?ta1e~{F!7t|^Zd2G=j2wnu`<3;&~DxUz`N#I#fSjU?*Ib2Pqfa%QX*X)Q@VIY-<9qwVOZ=mv&ak;pAZSKy>zUT z?+e*|$ivWrzMIuO%8HSm2m(}c$6WZjKT9*n=!rS=FC~%=*LTR{jP?AYAR8%8jY_;CFMU6;*$YFe0#UeN@W8s&}kqAdy zMXP1ev`w9UU(@~%zV_uZn(ns&0vlr$9P-^iSwhn}J*TBPrg3Imm5P)T%V=lnh7vMq z-9>DH%IzmOQu~wogF#6l+^0DA*i{ctooItLYe@{0j7hJ6WEug>gX#oJ*vcX(;qv-df&EtI*c-)vC6&Ar*zfW!6S-L?~g1YQqsjmiG|44UMwTU_L zn~9J4kxA=l?<_h36kxyAyl<1dho_?BbMWma*7_Om@8ifh?TdLlU2iLYAL6kA-T6#< z$H>VS8-n`)K^m+r!&V5c%5zp0mOX+fmj?&#n|5*#lIO1`kldmU~D*EEY9SF z99@Izz{Y&hwRM9pB~5TSdkzoBZo6Q%TSxNrJN z{qf9$3cKp17)drl?)RH@G!-fG7jm8P&pidl3rv zD@jOv?-@gb2&82sw&(j6p79ppn4n*O0kUpap{9yw#IRqEFBn~5M-#>s*pQ>IVjaijwl?*Y;%9!NASVTz~MY2tc8qVYa*QXH(Ov4w64tR<|q5q2lI6${`4A4?FU54N3Hzwx~?t?>$8llD;Lni>c{J z=m}R5-QC*D4@#O|K=Ea4j`DqWc^<~;Ep z`Z~K&?ewC>`wLOS_PkP+1B0t|-voobx|zCw?;esbA);PhonYE+pMmY;3yG7neM}!` ziMeR8ItA$h;o!w&?-Krl5!PTEoP_%?yOA$a%{Io187Oz?ebYK)8xArT)!}DKA9A^6 zib=|nagwo%;l$jJGUpFU$!}1fCx5osML+gb zS&p-q>EOSdr5_y#+ze{pgAkA=GF0b}vHJOMHxxA_4zpH}d3I^%Y+nro(cI`?D`VbA!h=^4j9Nf*>FNdVj_(VlyMU3V~X zkL9UVAEUYAq-Jhp!C2{7TGTiKVK|D&BzC+%<)cIG=T)^4QiMIhYDjFG7Om>EN&f=O zZ{d0QMaEEOh~rU)SO4_bDh-UaZDEg)XRv;ernlxOtki46LntP>{#}>%F$6@T9q9Gv zPUri2*nK4y2;U1r4z?!JTP19)9C{XH40Fa6#_78V*7YCcc*@c^;gurF@~OpE#J@hk zVWKyCD!ibbgC4!O6lnOpkJ4X7r|uTGzMxE$nzph#%%}soujcg5o;EFf`}{$ zDmKT97sthn zJjD=#K%IO#H_-@7cLCr9c%}J#lGT@Qs9Qki>f3?E>cQTkD@w&=uWNf{)Rt=7lgciE z;hE6U;$-?mqp=aj-QCE}6Pyu&Uyk=cZrAb+-G682QFQEp`XzVoBx32^^aoogk|f3s zxC2+B-PwSFjJGB_jhrg`f$M0ZF|K-<&HEG5Yfhq1Nu5tDogbroI*tG5EdYxs_PGai z1RL)w^hfXPtuBVPm!Ant@>Nc-h=PX$G=B`udAq;cZ^f4VgiF^TU(6YkNZeO%WoLl` zUQPn<=M^#7{$>b{ec~4FWBfC7ME7@EhH^<;naou?ieWO_oC@MeW!pEJv{p3ST@UIC zI+8AMb@Uce{j*uLTQdp2Y8GHTe#L5ksDDTOsGH<~F?h)0Q)_YAeUbb#0P=K7IdE0#e&N) zkF^!f{^N;Fsj_u7;~Z3^J7mm=TfH4GP{f+hl?g3_y;KH)t1jJ0EL0BQcP}Z&4s|zJ$toLbAgdMAQ$-NH*!1GQDofeAN%eapjIfb+dW~gZnkdfB(8gQ zqBIr9pEWd=L~r=R!I7szD+Jf9y~^vvV@RL67eFd3dh9xuJe%)fcRo+@LIv|vs@Wbm z@6ae*-+#53Pu$uyZsZII-81p3>=`+dEV{C5T6W9!T@>m6>ME?CY#}$Fm-wWTZT)5t zgGk?%?%IRj`s2#Jx}`7swEa+xKle3&BRd~PFQ{y2ap`UvCakl=9s)G-Ju(qV7kjtf z`4?QO=5r=zBC~eOKd4pj&anyCnXyUQ&&a?C4$wRbh~H z>@oiE`P|#xYNC&Whb~@3d2L4{$KMejba%fFTx}nYkLYjFpdYS2lHO}O!+Wre^~Pts*-|MJp-4Wb?FrtD-_T9c3^!r0Uk&OUEx$x(%9dr!K;%TK+f zTy@X-S;qi~(fG{K#5vGbg<91ob8 zmObPlHt#efKIXbAa?472&VAL>%OYNH&ztLneJmYI%!-iKYxcPSB~IJdsnIA(GbgNk z=IKY|3QD3IJLQi8O15g&m12>9v0Xcf5nA7SydH+J?p~*#H>RGPRFFPn4wq|%hUa9w8C%2?u*bh>;{%V*+60zSrkS2Xvj40yps>J3laCW#PX{qkT z_iHwt4!0+C<3c}pR%=-?k;VP96N7-#*XqER8=%xzSXJ+2Jr6F0OHhATDYE%C*CyQ^ z@pFs@GMFp4T*P#)NGkHqzGlhnfq5nsqTfX%rD@N0(Olx|)gmY>DOTPJ%MR1pQYeRU z0W>;yX@RQ(z$sYL@-zWvE?k*H$$EH-LkD-1BhpJCB_Zx+=lh`{IzaXOTBYU=vpX{$EKD0c_LlnDr4~M?~J%ru=^?i=hjF}IHRtDD$ zfNRPp<}O*Hk zzAw{v6wc$Joir)i8&$V>q>E)zHO?+WLFK*A-gGQc_)_A;n zGrJyBiQ^}=$~BS_{_&Vamt~q!`)O(7sL~RRDbqolW;qo1m;C+>%jxOKuJaUP!%Ce$ zcWd*)IF7z=tkhU!i&K%ECWnjr89k3iL$;-)qWJiaoviS;7rDo)k1$phjF{Se?ysv1 z{8$U3s#J6*$>4yhVCi|OVnWLuB`1bYcU*Kr-~C|%F>-{ z5LtOgPwunH9tX(aOwfB|=iaXwrS%q>H5dxNGvFk;VQ# zQa!aCbFD@_%2;q3@9$tJ9qq>k>1d&M?5=5y`3(#aE1%(pcmyMIYnR*{9NbcfJ}BLtU#v>F>Puzv#XI>JOkY zPJS;(-$$+PTTqJ_-~a(~zSOO$=#@O7seejut9Ng+m#*I(K^o4Ps30dP;@H?>+?#o3 z1!^ra2RPI=S}~kY!Z|2x-K7|)(Fpro-eIBG9m7UUZHnCa>?EiawRr*>%9V_g97bDf z)p$foIGzrKO!ddyeWF5UxBqN=G`EOA_gIm^1`S=Vz096od%JTjDSwkF)F!fI(r(6O zWrRKbY-Xh|^2h#YOf9IYm`A;Y7nYBzjePBkf0U$3MKy_L!QWuySTSy@x!&!hYHi`v z`6Bz7WBk-af$A^amKadoVpVFpIp#f{>(nki+MvJc88=SxICJ%sxp}`08)>{i=DW?q ze@dgmRNm=Tzm*FgSRRKI033(WByZ%!m)CltMdf&UE5cioIvk;-8yN0!1T;hC$s3y zBaUHSAmH7c`*_M0Dv36cp_S>^-kXr={ny)JU^QxlZ;9I6JPtfbHk%nTiJ8jX0y7-9 zY)YpAg&0nxAf7+A3H547Q1js^NSosYyk)WM5Qqo941DOoV=|Fl6Es_1WNxx1g`%szFtBg%@@R1JD%4)vY0IgXWPzNOq!k7u z6%|UQM9OD0Omv(ybtAE^PDlTM`9J@f98^r#wD+-5z5mt4|7;O-9K5Uyn?H)P0sQ>` zp`$mWQUEVjY2| z2}8@T%tyy-w;Ol}SdFAgZEyH#_^)R{1h#vgHrasX(J?`|VcW}y+T$ZAkE#>9Zro$y1Eo z>QB|r#JWY}HpbWsq#-`&@hV5~coh$L$HxYxpA#|y@Qe*_<+xsOk1G)NT`n?(uJ-?? zyIuIE3P5zpUFPTUW$RpAfyHjpWD&qjq{LEZE3BK*m#FX7CZ?FbmLvlY>WnX4XcQ=L z2dR1{rC{JQ_y|Uzx)&kWib;cqV{XjiKj$29!aG-K_$9jn*oQX07Tih$L(^GBO?+j~ zm(}t=eBmJ;Lfm*-?0$=`bAGn1q0Z3CeflQ2=(52M>p$YJ}{rABy%9l&~uMPg+TJw2~4NPi2 zSaR%tX#zA{_6GbSx-T?;FR=f&CP3#?Tal?4Y~ZU;Z#r@i*z{^lBZ_yo6}tnk@ubaQ zuY-DfNY#IZ4fq~Mg`D@1((Drk&fLM}Y z^eUXbd|095KHZQ0geahO3$}J5=E=JDb-V`f^&J+aJu%=P_6|@hD_jIcCCO261{i>H zy>(u6VcnjD?QR<$HPBa=+uIHEszVfmDx4C2sq4lhoeSs{_Hl7sH-MTtKn9u!H~>iu4xZDfZ_fY8fcffk>EVxZj~0LrOB zk>x|lAKR|a@IgSNG5NTcPc>XoJiR`;=A!n3Lv1EM(f9wZrH&l(mWKOo+ma+vi2G4# zO8)nSXh4IoVtzz(s)`3nzMY^>p|YnnSpOQcXu99&xc4N7YN}di1E|qgu)Vla8|yr7Wj^;jhpNM(xC&1Yl#`2K-Nj;rEJhm?Sd9MTTB+jws7TKm)i{AnI!8Qg4 z_vYJ*C#v^)YJYFs>px1uJ55KHI8+tL$d!hL9xba%L z;d0Yj8D+_8o6x!r%c%TC>+6!Mvvq&QM7OQ#krK80c=HXW6G{O|r z!N~kvFNXy>0aYgHV#}%VK`FruNU97*6qO(CZUCAUVetEFo~wBM@ak^*(ryLmLXQC% zuc;*ybognnQzRHLyyGsOMmX>F#eN6C)j<(3<-*`4;L1?pX*uhHr1RprhCi;d2Fq!u zazmul%Z_K|(o(;|NJ;M@U}%?si+0xts_Yv5QDm5UIM!DB#$9s^gwzJnib@3X*?n$( ze8wE+W(8}~glL7gG*{!p}H1K(hSTFB>_aekz$^w7A zh@Eoswq*Agp>f)P?E+@(;L?RhiO2r2C5XEo?viby77>??_i|k=$nb2kr7=#S#a6H7 z<~48Bj3{f@bFVW#8Gh5JBVZ{&1Ru9y5ID?{{cP9z^6L6vNY(SH~V{n7qBg6aroMeYO46S)-2khY2qP-;W-sLZ#emq}^4 zPH&+pNii>|ZhlycMLn8e;=lRc%wWnqYysS~0PovWh*qFo!PI2{=V(!g^i1w+<{8AA zs0J<#`?H=HM8Gie=Bv9oBFMcZiBxSt)iUg)O=8k6n(yF8y}Yg*f;)1>hu$0dMjY{N$nlR& zdr;yLxn{yGziXM;1^u^##OdRg!NsZI&^wZ#FH8vRgdAPkg}f-SVnpe4=Hv30Zew(! z@0S3uk{=UlGrwqG7_)mQ;^!~;df_Kxfhgm7EuO#%0>3SPG6J8;7KBg*U}L?Ub9=lQ zuOt}v8%#`afO|eBrEaTx4Ojgp9S1~MzlG_lmZf4)pdl za@Fz%zyd9D<>#Z%b>Ff}dElaUr9RN(CEVrPat<+eMr=K8fEj$UPpOO>XK!ck;L?h7 z7*%a4uAs~YG>m{2$|*I%$NDl5H4T@c8omA8sYy@7mfN4rQb#d@GAj+mXzo%};B25% zlBpi2GZd(v&+C`n)?EUd<&o)bn7+vwM@I#-<&Yl#HF-B++x64`VrijNfy|#Htj-4kwcB^KNMz3GJ zAkS#qts+XFt7rGjAFHcDEZ2d=$Zz4Yb_I?eCgdT*6-3t?_SlOBDeHWsp(Nd*0L$`kz7Y1YhE584lK-rtjSV&>`n5u}|=5 znJwkn{uu#5}MJYds{*4p0a^X35;StCJRMu3agLS9$%KmHsMv!S&qol|I*=lE;}IY`WK+F>joiVx?6=C;2P|7yS*m8x7rSxWUq zzYkaBp}Ju1Vee$`#cSsu6_oKWo>*j%-V)h$nsWRA7)*iU4%g>YQ){7KX(!G+4s4QiRG+USEb|`) za$GrToU>*{KUZw;WAfY$?ziHJ=xNt$FVy?uXK%fO_k5DGhXf`**SOA_4gm{qxvk0i zX#we`fr5)dt)#0#W(KDRiXF_!)lu$gx(Amg|5*8e17b$1J#giCV9qvNa4 zL3>P$lM*lXz~dxdQ_=kZ?47IwWV3rqXRA08Y9(&Fb|lskQ^l0KRQ+(mzE9GUiF}!v z#pI{a%35d~iw#_dq0VY)`lX7Z#l$7$EBhgAnn}4W4uEI-VB7M1Fzo|hG~oB<+X7B! zW|X?CW%kDy1As|7f84td$L=+*#eQCrUrxUJ3%(i3f!O`3597+x%ND<=4?qAHnv(oz zGr=Q!;&ylpr%=&oZ)VrdQ>0K-obDss4y=Jl&7*SDHu*oWdYB_McaUY&CG!l%todfn zo2)-bH1NE(=UciU zexD%RC98VcFIofmf4ufT8Yv3suooyGD zhgamLWpS4$*P|#aLydc=EJ0m%3J12X6U0+n9HTJsd-Hdrlq{U$QmHxF?wr#MSF3L$nI7+AMX0^a0sR2YLbHxhf& z9(3%aK~CK4)-x=zX#Z$8n0P@M7M4n0+9P0_`>CpxU#ilE-0%AW-wXh`$+JF473NnY zKZ>BF8Beo!VHlA9@ua=o$^G1)#Fb{?$BOAS@5oK{vvTRJrtrJ-Suj}JK9;$ zy^wC%*J)qp+>UGIq=C1-chVnem`s@J{7x|X30`5i#pJ+h$DK7VXI zrWee>P9d-^&EpZ1&UvxL&EBX~6!KlBbf_hnl!UI5Ht8r6?DRa#RE;@Q-qa^4id9M+ zrp&N;D(~MAx10GPa+y?~6~|D*@9OZR2*(q4?q9yIF*-}x@%MBp6?6Ffi4&h#A1TS! z*-V>cL|y&bAF1HTI`^`_)y`&DX2PW-Wp)B5tTzZGe$jxnvo$yHb3WmI4@oaA$)Fj5 z%McDSQp=lEY#s%3yzWkprkIoZ%IQ*Pp=!0_p7)&olZ!Rm^*-wP!^wSwdS;GRX%kku zLgd!82BHvQn3(<7{<2e2KvKm_H$u7bO!0$YExPsE`}JF5W14+_2ASrD;^V{nRSU2O zgonblna-&Q+PuPYd#-`O`C0l3eId!nmSwN_0ZoRM2LPE!MCL9Yi+Eesai0|{O5`F8 zV?#g9Xp{;faepxTg@)lsGPPymXPu^6T5K|P&3B|IbzTt`d}$3Q}`naee_3B$H&(32NXgYGpDiQm67~(!Xn~;xbcrT!%NH^#=aQm zmgKD{Vxr9;Vrn(37?Z#~P)poQnLRyI1y}XJg(f+dqbFjAU@9o<00N zYqW$iRK0reOFC9MTp7e0R9`-v*C> zr?Etfo1KvTL(f-UT9Ja}{YwIP29Nu3U_~p&VCh@(k0K%RxO>#q0C{Nfb+X)eqNIFs z3E-Rrh+rC+l%9X_#2_hesBHXNrrp74b_8EbcNrzn)aH8Vv2wi2U2#elS)R{)TT-Qm z+Zr(@*P-DXd--BK9x(mcALp@3y^4iWwH}D$l{Bqd$r#V9vwbGS#Gosyn%>3y<@;rw zoTOi3c;KeQ7Sh{X2#=G)L9!uB=hUT)`O}ttJiXQq?ug(t6FR@BNV;Weqoy`!DUp5d zU|9<|`Ki;aQ$(H=3|gL9_zk+V@iN-Gsll6dA*Q$2QW%v*+=$rG_Loa=4hsBj87 z4P0h_gcjw(7F1>=X*YkEu}yJ871&ORRAt9j_-o0;h%d`46FQ#GqteAg&82o8EmsJj z^(Qr(|8(luD?MB;QsSElrZ`$0>swUu0fSrK8wEu*U1-o9bLjg-<2(gKo7BS?cF9n!EVrMr>t z4k_st5a~vwOG2bm>5!7{c<1(<8FOr?!iFF zbJfjZ8IF6TJWLyQ621|`D1fa((7^uYfjb()+`6|Vye_6P<#1az{2<8S$Ev#e9=8ut z&YUE#+Pv@(M9(6e(`~OLTnP)s?3%;Z*%Z+`@m}`BaL_lc2TX9Ajyhau zZLP^ul`xfZFny>2X0=SE2eC`_Z3yZDWwP>(}I z{nKVe(S{t;q^9|wZ1<65UOlI{SHGqCN}5Ip0sP>-^}gv%WO2d`#}K*G;Zq@lMDAY3 z$?bNyE?IdxO++=^_Q*l4SuhR4ro(5&}caiLd!)rb(iOVK;c!!Vh)5O$ei_h{p0a#-N?dRNmaI6Fn7E;sKicr1AX+POaV^-z#AwUQ}St^37k3nLTu(%IR(9|r!EKz69t^_ejdhe@>MApe03 zV;?!V)d1N{jzMz>14XFg*Hqq^9yQF7fH2vu!^2&DAd+~GnudIL7ys#ku^Gz`t@CpK z+B^@aGbjqw?HgR6bsA{=-t#1KyZc8s7>65Uj84z68iOVfiw0P)L0VV2vAaGY4ku1P zP_5^0lj6dP`iUL6TB?|jEs5R#jhOG|VzH^$++zXvvUg_RRcGgBE7GOkA)ZvymPwc& zj}bIU_Jqb_c~eNd5KPb%=*L zBo{ix_CAVr*eixTIy-v+tT;7%Mm?A?H`=THE%j@HbVW zE?t6q4F-+k0_|!<2I$z?$4bpkQdj%@DA7Wm*z^Mj#8kfkQg1jY zHMu_j88f}pWe~!blFVs-SD_48i`Nh>3Qe9PYwU)A$5G9cr*C|l4b^cVXc27~9FYsVel#)xGM+I4IF@upbK( z$m&luSI%!mr@7X-siAdpSIzSaMywu&TZgeO`8WQ2c%;5}4+rYgCg@8j27j%Su;*KU zxXLWcJje=QTwMv5~@BI?7Ky>-Ed z38h1m!cCq>(}g_ShY|J4QT2K|#EuIb`%mfDoK<>kiSm-WHp#!(P>a8 ziU!sxzI_(-BqV zo@F^`EmN*ns=_paM{tJ2k`5Xrl!#)y~E6R_t9jEQ;76UyOqKyXy_;U_cc+=MF!#9IYI2(3tmz6$z z_q$3rK4>Z}Sc?ozZMDZAWW|f#c75N97;{o#zxLIU0a@#Yehs>jzk|=BO-N)se3D?6 zWVl_>LtF?Q^|>MOJ_%k>0rRh6K1KN=T~FX$B5I)=qG2D}jjV9SDPN`!ja)M&PNAP0 zD6bQhv3U5a^q>U7)y?+lBsFGB3mgj6^nPih%_QPFwYl~ZDa3>e9GO&vrFUg`?(^6Z z4}^~-gkGei^z!}GzC7w(e&$P#QTr3Jzg7RS)@9-SqACW{tcLw-ShP@Zf$VmCQ3Ic^3!sx%1v4P-Q)F z-yp9Qv9Ggs-^NJ)blx?Xji}VDiO-T!bamAEgx^!lf`S+$hAr6h5d$_U7I|Hl9_mi8 zFUtpuI*%P|bx4_H(sk@zd7sy=JO|&go;#jk%+fbbD z?IH$x$Z(<9w^WjARrwe*Gd+G0i#b%(7A*eltl&u%5>$Tj`+U=*fddHE7qH+HrquNm z`S=IjHOusT&H~@F$b=$3wXR>m4?|Xo=^|K5fK*Vyp6ksj3wioTo+k@|qpCLU36C#%Zj)fN4y}uEukY zn{Xm_v1U0-ftVh{7ji<(;Y`W*)02Z~Nx3Z4_j{Rce?0mLJZdKqwIL!l1^mB1l62lL zm*oYo92C9Ug9}1RTMepDhc!iVPt+%Q0RmXVoawJ&pqTqLjgR2ipO^3757HYW;D+{{ zA(Xv={ciFb^5NE$vV$Vk6tH1%RTbJdfvZN8%XHeFrbRB*sFZjwpJAmNvOB+W!14(# zsu_>9`LbfGtQ~zgS1J~D0VnypjCvR>^#1j;?*|vKcv&Y$`Vh9+;@q{(zAgaZh50|A z%X{8jowyTPC57(+vux~ha*ryRX#?s%50ZoooRZ`R=UTYbKX(kfZwf;MsK-&f!>=DY zJIy!O;hU=sZNN57Y1kbZ;lOS&`S|BdZRtmyPh4-IJxIX%n{)|`#`MdN?5zHLGcQd` z=awCEqAZw9w=Z-#y(OAb)ClaLv_@-9+{d?ORe+Q?R%d{#4lm>XcK?zx;IBdy%PC-A zt73w{Nx-B|0l-g<05Te+=U|&EN4^Al4MK&1P|gn(owz63^B8(v_;_C1(911?Xaj$kaic^{+~o8!eR!2B2oeBa`M801zfZ^M~q=lxM| zmI25g|KVj(FF=^7!80ihCl}QHpi)S+Jzb4PP+gzE(Igq5L`tI%|0ejMbV5(2u%FTR zM~yD4p=|LAz?1{REtTp%F^43Hu++g7NChEHjX;p?cL}I?HivZu)2WI)QpZunm>S^B z=5+m;m$1NTBy7N-0g{?=)7Vu4SP@ht}yL^cYb9?W%Iu{(7w<)b(8n)_^Q2!Lt`AiJ4pur0pBZA`{n_^lbc~pG(ZAX2p^oYSBnw>x zG3Q&b9HlE?545#cdd#ZjNJP9f9eMwS-0M;wytGun!w5K^{M}SyF{~XC*ip$GgI#`LdxY9m9+N6WYClwx=LIDGxy4M6q)fJFga|~f$ z&Qofa>OLd60ZI#tZQ8V7zbD2zh_#g7B4+>ovt);FKN;S1ri6I)thB4M zD!YGYAQOoU1{;Yya`=d?ZY-VQ%HzLxm`o8IZ@uiB+9$BhP{TAk!Nxfo~O z%aY^|btRmDIsX*z8`DiFV+r!K0(0+v&8(d?(vK*?>pD@Wq*Qlc1)#+vs&jnPv>IK? z2gDI2^Qo#=%xTy|HF}NQo8;aWXM~}a3-8ICo6R+Sj(909pFdPG9vIqD;&pSK;03gD zceh`&K~;v=HS-l)ggv%SuT|bT6Sr=Uwoev5-o6HPfri&Qbt+(R?tu%E%SmgWGQDW} zPIJHm!plciyin?Glf#CUA_dar9O!J3%TFXYD^Q7|uc+{#?{j8T^D_t{M^IAf zezi+wB1%2OTq+eyE0?p*3>81|-UBW$vbcfeX?=b|g4K`YA9$|jJB!uJsZ1E>oc6b- zf{Y!S1o9o%W&Z5Je;sV52vN1t%w5MUxqwGtCrvTf@pg30EPE|o;^b)ry%SJOTSDG@ z=FR!DM&P3FkG*Z%AN@+vGqP^j#|P91e*6&bY1nOgUl*93w zM3bbW60Q5}X{-!*bhtNjH&@VH!H7}WPw!(89+J|eAtis2pdU9eMuPuNhul=xh1ob( z(Plh@L;%zr<;q3j6oY7;?8aa3?U&stSEv5)p!barcdYqZz+%}q(w`KA=wK+GXYm~U z95nnLMtoAS<_(;9Mf(D8hq&I9mb0}C>mMCpFD%wTZxMipera9^B(X60V2vo+p>`cJ zFT9Dv|2jtR!W%NEKdDpDL;Go~BFu!wcGvea9DnG7)Wy(qat+s;J7k^o# zqGWC}*Gy8)`nyiJrJ$wuIJw72;E);3On~4^@)KU0;pGP!;zyQeN&Vcz3Rp-0V>em8 z*XW@ytf(p2@pcvKCx@RO*og)|K6J;M45cWnGd(5}AjhXwPl2nUTTm%dW#)x-iO^6* zKcQ$0TX>SXU9FtOGt7eVCtpDggCnS9{J8mL>UPleM{c=ul4P8Y6~PeyNcsJ{S_Zjp z=G5`eZ=8wvUCK=2N(!F&R3pfbZ`aQ00&lws-!a1D4uc4?n#MYEbzJ7ud5o0gw~+&A z$!2uX)BdiM?Lp)D7Ts%`#uWoKtii_%kRf~nZZVl$nNkSNINow_kVpjdw27j^Ug@?Vo9TChsj`dkq!+ zdOIb_L`Hb_<~RYpzeDC6m7#{HU%YQwZ8O2drRFZ?*a>?#V8D) zaFAD{#b8N&4u^%EnyWf;z`95FMJ_*lK$2}4qm&a86C~bS_BffKsn5>cq`5B65}N)> z(bAZ0E_)hz?c%u2^;J1^m_Ky$&I$Qj0*m%n(tJPiq!R;E(2l_#sXWu29XX}@Df7wB zpMl1uf#q+m8oZBgN?rov5G+*vZ0<57) zGDnXOjD^%una%CbtjP^6>j`wMEdwviYbJR5S;1{-2~tM2$q`mCv!?m zM3O#w{=hM=KZ(6NSxC%^rvWF-&vA2H7Ski7bL^7JY2lipt+gT>#JBx#q8KRI!QGJ$ z7-3i_^E+;b^=~$NlUFibcmD#m@CVwdUIC6gQSTne;9`NLq#d6D%~=V539VLb)|2JD z*P)4!9HMb50=4bLbNU=cVz0RN8)36~e00Yzss_W+`vgOn(&w^xOyshecz= zgaCyAYv>Ege0`RDvFpn5GJ{TcNctNy-USX{?1QSr&{rkWi7Zwi^)B(aI8KM2!CnxI!x^;jviSyBL(onz4SwggDYAmU@=^j9Hl~9nx2SApSeljR{lR6%YdRQVJh97e&vs%~L{&EkG5=N*ww<8(x(e~Z@#LM3@nvqT>4KYrD{*MnY z^gGC@NjXZ%jns*B6rS|7M@p1x37pHy)*as`;ks7=o`YKcV$~;*SL+;YjQI(0`c8g6 zT?`ZEZH_&hUU0sF_(e+tbQdFnv>S6pzX+MRpoaA4X&%J_Tw2$8}g z(|)36i~KvwG#USxRB*}-?cH=(GM>f zmkRYM>+9{;G#yMp>SSTtD3c>rNt6;gTT`Y3Mx5D~2rD<(NYo)kxcfZhd~YrjqUw$QlEL^ zw3;~Y*Gl6IFZ;x(!JnaaUwF~~x*vZ?-8&r-1ty7G>pD6ELJ1!#q1fv(`<7rH*N>gpx zP{i?>3rndOyFgrPD!VhZKK%~APY}&Oz(RD~xGf0($9Z<0XW#xb-UPeNzjwU$?|~YaV7T0{8IXK;3p6=#;Ds`hI)a~a( z)8X6@*e7QmfeLvUw1f97QY*#hubiKo$$5?;3^@Qm1x(!e1gf+ADjCx!#Q~m&DYdpq zsbuw2Q`ey9pGf-eK_)*6&HhGzK$f1s1^z~x_-efipj7cfB-HYqfwQ2>uE9hlW<^OJ zcV#6>vxF(?C9V^&!n(~%6>=MO5a2Y$qY<$5H}s8~e{Nc>GZ~`dHt0ak$A@p7{G7Pf z;&aE3f5%9UV$l7maz^>e@oZnJ!%uT2orck$L7M1fb*JBtSzU%<9pdtSW%^c^WewE& zF0h_1z|b19&O&)FvcC%K_gCG7isHkx*w%rem(=*h!kdBFL4bVCWbAe;JSVXxF=*43l1E?* zoa+INxQxQ!95+V4d~J=|2l~T!kbY0S*xvPd2Kw6!VAR;H^v0Yo_`$05I@_gw9B#)w z`l=(K!PRgunZzL!Xa#L-f*U~wSMhp)n0Gl^ba~P+3a{E7ncEVLE6Y+Wp+vpBE!!RZ zRS(AyU+hCt5lOPreUUhRRSrHBNaOK2v*N zpJd{&a!`Q1yy?x!4wrmt5aA_=Ng9f?g1g!Rprl2_8ilbM9M(T(PcLf9WZ4Ktk0wMc znZnC8wR=FsmDqnM>Rxt)9eyRu*pgB3Y$easb<py2-unO-mjXgRS;Myz&qy{gU(DdxUyx zqo}RM^#Da2-3CLJ04>(!RQv4aIHUGt22@vk^!aEkyb*9U_Mj%NRu&%o$*}LlZ`2c= zN$LdK_|6!xpYJcBt0>e|5Q>^9=?{M`w0QsnhVoNcs+LuZoCcCP?W@hkD%co08emP9 z=n2;5irVVqU&gT02R*>6VTL01N?teLTv_M)R*24keZ8{yM}%B}64EcD3>Cua^9J>_ z!557$%~A7*hE<{B)+spWVuB2~e5ogojx@UmuwKPRY9ZP=1Gk12w658~mSyJo9C+?| zj$!7=KY9*kL0P}E$REm{BzgGqVU$3~t60;8YsF{yB`S z#fWCBK^?}7ftGjHIagNpPQGwa|Gmf_2o2UEX>OaE&~#WmBt#oG154N7Rp zBqKn-jT4*;!w~q+*K>*mI#e?#u6L>@bay^he%;sTv?AfMFtN-J3 zFF^ojEx>q!!^%{)igWJwu4o)jpszEeAPKoszg&yDsaOa35a1$}Pjo<1B@8v=(|5I9 zbXO<{eh|S_(*Q~X2jVHqJc@aw(y5EL)$Rcdl zwTpP$YK3Ft={xaMh14(F6u6tL@!yTj`t-K}iaUPvYi@4;v%&)h^-Mlj+JsyIBx&~@ zy!BU0Rbbk_kODxw2X3fx#x+0feCw3Rww`W0qVb$G(L04U21Nc^ro<;ltb!CyVD zSTND8cxm;W!)!xlx(8+^J`MU3GF|_jgFOTf>@1#Y339``xf z760EL_Cuct`zfB8zXq{D9Rj=uG9;Ln8XmsZEJ~%ipWPEu0f)aTdyicIbd5#5tc73u zb7}E)EI}Oez*o>2&}?i0r3fo8W&+r;jo0Q8!>a&=IH^i)x&j)W1{KU3khL*uR$($N z-?g5yh=mrQ>(&bt&RYufFc^e|7A6$e5UxtQF9Z-IL)jYBz#gc{{4RqXH6D?~g`((L zP{BHbdKGj3-5-s+qJhmj05&&TQo2B!d3`P#psNTkjSiYMazG8MeWO8B9W50ae3uhi zsibg{leo}N*)en3_*5~goMy9Kc*g;exWT+VPAt1^=ybbXvz!h5sRLL1wBF{0HIK8& zLti}$8?M;{05M8q?Jt0|f9#Hy$J^tU2-tHcwp%RMb((s0%uR2Lh)?rpw)yZ=31#s_ zvET>&4sUr6;j%zW|7XB(Bdn}0W(D|If@&M&eU9XDeAJP34V*oWeTh+Wb&hE^`q%+< z{2nwqR)=)kE~0G3iWma?V9|51q%F}}RjJd&nIBnD){GZx%@{ZmuQ2G^)c9&#Dr}%Jf@V)hy{rwZC5RUg&oziRl@GKvs$wkX&eSmmd(c?wD9D4pKKYkk zXaU`mhwnanBbN?CiMbvlnB`FfXOaqfHd3_R$I1-eQeic~>E=g2DvAdvf;vUl#-ejJ zSr&C6rE`PfpdyJjk78pVi9^0$|;JW6p|< zOEjL$n{NewMb8J68k;-eC-T?IAX;Y1kP@W&zx$wDzlf*~g^wBROJuDzFy;-t&R(#hkCooy~A9h0^psTTeOXc++h z%bpViRjsXnzRQGK7$YtTun9-v;^QRJZehvSUO=Ip+j8_q7gm7}>P^Ds z(YkNKouH?y)j99NYXG)I?Ae@hSnq7Ty(Ri-8J4!~fK8M?jzCMmGgJZ64sM#!3}__J zVsKAT{KEb$-Jk8`&w)=iGL7yiN?5V}6Aq@P_nsf+#1+RNH;F3h-teGh9zHi8*kZO* zC1&s9DG~6rBe)bq9k)v%>I2BvN$y6YM)_R6;ep{o z%GYe6^HgQsX5-OD6M&5*r{1DJb=)xW*bv;Sk=1c|krT}9wb&67^Pc1F#Qu{XFuOLd zAPg};e1(KgYO+#BpD8~-4Uqmmj6q>>q`s6VhJmbRTK&*Yq9F05HWc@v=1>tBn7*J~ za|7VMr$-1*4AH#WhBP)xGg$cuHClk;TR9_V=+}BPzoWcS9hqV{Y`Y|&lGRsYy5YFb z|HI=%XLFkMH86!Ye8c#q4TB5FyVW)fQUw-HUOb!FP7NJDPF46s$)}pdqi%t- z^763ya&!)!AMINSYDLr3{E2My*utpVZ2HP6pRb(@%%EFa!O+F``1ovc0%O+KY4_yr zT1!)%|C~I3(Jo)qW{@$NC#zzu?q|1S_miW_q@eR7K0J%!XM(!boOU2vuBwjmbZ>GS z;bThPz}Z;P-5bQzMuXP49<0g2VYa?>*hdcrLz%Tec~O5{(U0aqBBeLqq6}l!5*M z2El{6>fa; zf)1H6bzR)+Tcr=KB*IVzPOq3*&gSHUYl*AP#gDWY(7lu&2bS@qZ}ac+w+ESFc2Sb% z=rr#7P^R;qe#01aUOvOfeT>QacO5U&bH48$?GCE- z6Onf<3ZTyUHOX4_1;Pawe7=+PAMwo_f(lEsJ8s_Op|MX17M|m2bA@MF$ zIm{re@=fZkQDQ1pdI^uK6S|#&7ax9)mcbJZyV>mrY^gBndlQM=U_l$iXwvje zmxKTu0h{*9`{cf-_EX3oPcetQ%-d>zQNJ70Z8gSwgo}juVsfuJL*JJC<>=ei)uIG` zVYI3KJLH;f=qAX%tR)15!s;hdmf~Bk53U2l2|~w0zYtV1mvE-%VD4Pav4|z*=pYX+ z_;30&6U>KT7{^>5a58ZOZQ3+jpeWFf^Tqy`Y$j6=g$7%O?Ti}@VH#+wncTQv%J{9v zn7zcD;L4uGJPP!xk$zD|uE45@BkX8fOBI$w>fZz7Eeh#Ob~*Q{7?shy0$&e%In5D#IuI$+ z?Nc$RlGtzjOmh%|mO0b%;UPD$-HBqS3g@(NcH+ThMp1341kFMtjuNf>&KW1+wzlO`#-Fp32m0 z#8qL-8WM6{qOjg;Rz?Xl$vPvU>qx$>Z8^4%Wpz-V!a>{9=!<{DS(z@FtGcCi zQ$)83Cvl3*p}K6W^K7SkF$?S5h+FC&4b*3aNM>2o0Jn}3qJN2@HzcWh0VhQ*DPHU< zMlITj7G3Db&U@^ePe3O9p-8v2T>R}<>E46Hy$B zfgWx1OQ_@dFrvVJ(3!7qslejU0R6b)o0j(Wmf|Xo06y3rQ*LZWY&4LH?Vir;*T^v| zinkeVnN2O(_>9?TVlPg1zEkG|ny#hPFtnA&LCgH^qP!}&d9~fwn9SC)lX(FR!cehJzzuCf^%T??{oe6UJ znBMDSv(;CW_?ZdX)HrEk2u;xXml{=vLar|qPtG?YuKrM{umd4pOd&|QJV2Q%zk_yI zKa8jFeK&xP$^uGY8kX8FTzCKIy5^vPUL%(jqHzQd9(2L1wMob{!zetJeZ2Y_tvVWoDR(7E!SS z6dws7vLw9{%a==|YMQsTbip{G6b+C++YAj9*%YBJz!0#C)a-U-7Iqf{)jsIf z2>iq4_XfA{f1DrqohK$?w%Chi2p{yW^Hw#bNFB~9M?ojb4WH*zk*#hdFl)UIPGHhl zn@b#dZs){WUpIB|DhMIC)3t4ZQ*185>J4x{_zs9%7z*-wr-+_D+k>>1<4 z&a03$R47Drn2(UVIg}HmEX*|=&Qh{AdQ3qdWII-*Hdx3*@+fEz1JrYciB<}#Id9V> zSoo^#Z2-|=r{D<$c&ZZAdVc)PIe-U!12ACs1QGxx6hWJtR*LA!mqDGHke}@yO;9`1 zFK_tk-)SCt2TZ7R_{)n_<~lMc)B}}tS*SNTs|CEf(*0g4lePXN zYEH9JOgswlPC>7ymLwB*`8^0&wCRJhEk_F!6^sGt_*xvU>&J6$o}?A@kCeNq&u19a zUjVhFftIfq%SQ$kTyAO9Q-X`mF(t+VLPi+DARYQ%HU(dUrCL|2JH0q`v;uV0NmOYZ zU9;zmTD*Jr&3!SM_9dcma&aAFrpL%#!Q&;$`H>W;4FwgQN8R?oiUh#a>j51Bf&9Lm z?DB_y(U?af-XeQ$t^IPaNJOy)VZ)ZO6CieiX>AEW<2oj(SIM=5&(y_eWPv_Fcb+k| z3cU}|jkxlEL9=1asr=Hvc^`#92t&NS)?Y@Nf78fJ2!buz=XiyH{Qux2z?tZA*GQl6 z{RL3|{ePbuEM!)OlVl=0&(Hn)=%1AV`z;)}hywxG$$i==9$SGu@cZgu29&UJfeHNcIGvB} zW+nTv_&>bXUnf;~0(P8|cM}0QRIm@qplIjd?Ha(2|ND1qp<`O+U7a+jmQEj{r(CAWuKb?Vow&2W~7tb{-UJj9VynPJiEK z^h5AL4PQgfTjS(o_i%R`yxT$5{70kf%2Q+~IWX?6bhgd%BpLFQlUrx zZ)dcV29M6_titiuUH!LdP_PT;ncAsz2mI|^;qMduIkk`#m{(t!p*3I-{&^<<{Qxf= zh;UH7LU@G!w=?!IgMp}D=^Ou#MfZE^?}rKLJlNqppJr`=$nnOe<}wqWQ2IGU=6#s|8bEDnGn?y?MFCtax(m%Ku~!x z@?I7vanP|9l;o=KWs<1CD|8~6)XRj-CQ6uPlR09538^QNZ|9xk31HUVf(!%(xzWHf zxoUR%Rhct@FXaLuJZ!Tw{_ezumoJ+_3-!9HcGwt|f^|r?NY+c6#hw&PY1V{#O(b3v z6?HYF<&_>BI?h2|XaDOU|1;Vu6bJ|4HC@hXN}5$BF(gk6{FUJ=a3$We<-6_?Q1<)d5A zKTu9RWlQkltj(*U+rx_I-LhHQ%mRS<1i-X@5)mItct|YvJ(BF%)8S}jEuYeZ1=V78YRidt2p#>n2hMT=^ z_K9DsUZE4Qb*v77b7WrY2R)z#Q9E&fYlf+3NiKi_t|%nv@Z~}2kVPCDgZ0Fu=mA!; zXK2%EZrlRp-^n>H1k5=^TOwYRTQk$=emq=9H&7cevt0orTZ+PLnSOhfeT?sl1CXc- z_RP2Xy~>H;Vw(x^Lw`z7CYF^73T=qetP8f87;H@Ppp!Fs;|r zE}d*L4amd89Cl_k(p?r&3e`%}Lt+Z;fz&0HNuxr{?Rd)+E33eHIp+Bba1F06PxlZq zrhvXY#fzoUb7>erzXK#EK-y4-JO!g2+C&OU@0890utDv&KEtf2*a&oMi?00oR2ncY zB+!l;;6;oFypt|E?=t2T*!QT`DtKEi30QTR{^9P2A*<+jfpn6Kd=4mfLW%FZQ{Z#m zHwrt{0nq;zpscu5k%tQ(eYv!5+>`K84>$S6!)0;+x`&k08;TLMw-YwC2^2c|hZA$Y zfPt)MK&G7wHg#BOaln22ifyVyt5yzlQpa)y%+)Kvuy+wtISwQX^c;E>FEm7u@(%OI zKe++=;xE9@%A|P;1PQU=wQv2a$6)^T0ul!C3k=+^+Z)#8nab7YXcF1#iq84-QlQ_*2s-1yGiLb2PBjC;O$pL7?_x*f6$_OGt)>$0C zV4QA>ew@LNcGqa(2)C`OF6;h?;IbdJ2a2< z(Lc;5XUc{vQ>QZv7Akxk8lv?q8m!cTY8x_D1eu3(jj>Nnw^z?P%~;CL!%PKC7^$Pr zr&h7?S4aS{vvlun0bikrEv@~Y$di%)iKm~yd%LES1HbJEc6=*Xw{f0j4HS~3SIt$@ zfy(<7H(jTW#tci zI@}z^>XEYY56>jNb^9WsG5rEHHS&I=!ae+j+!|CXAiRCza|9worLxo-1|>l%MZ@dl zlBRRBqA*LdhV7b}Ef`$+D*r8Vrx{KRm+{;VkX4$kxi8m6)iePazB|?oOpHv5e`i!UXadcQRaA3UT`JnW15dD-^~Mm2$$E4#AD0oTh)$ z>dZ`(Q#@@nx3@4A%s+t^9JnCtc6v6ABeTiy(6iyTLG>Jq0sHa9&SNn7;$OsP zOTU4=L{b%U-6qM9&1Un4=JPjW=LA8wP7l?x0C{_!R>KqUu3-+ZdEiLl$vHFJ`^;m#WOE_D z4b*p=PN)+!oQ2{+uNI!t$eO_$h%Zc#Hocxa*)}~ai}#^>jNO>*p%I%`@D32}asYABhvJBAPd%(!5cZ{j_1Q$6qDO@Oh{~$&2M9#3 zgVYsRO!t>m-$YfJ2Z}F7Uvg@JyyyWp5S!I3kZW0#2Nb*%=PByAvRKVloHX4&$9OWz zM!ikS&PEG&qtA+JxX{3N7$ARFV1(e$An^N`n25E?C*u68rhx73SjcTKummN~Oqdc= z%F*X>NZ5PvLklw{K9pAJVz{k1O{qy$0&zwzs>!ggeA`vA>uo04o~`>}4-R%)oGxd1 zOt;h>#SO1P5Fx!?(;rERoZ+$P5yTgoBKUQ4(M$E-y+i5i znhb|)%%maKY%>_c?zrSx5aAE9fM<5VQydzV`tkyOsPpbaN9|w>3E%Z}j8Iav7}$3OhF3a z1qR5SlD1f5grzLg3HUF!EV&;$v*OYv37-4#T!KEJVdq!)k8r6M-+=D7^ejKl5k&YP z3t;OFVcB@Sc8LL?N++!1R1Wrd0yLUNyYsE9^5OIb!Kr0Q$oas~ znd}nYXtPY;7*5%;fnc|=nD-;-s1t1L#zUjQ1rkP&`E8bldt#`mr!dW1#R(AE%|m5Y zqXI#`W=z%%OT0iYNEIbZ9EVn}%4P44WJtwZUXP>PN>T8YLqtp)k9}*WZA0`!$ z`;}vqj#?K-wx%i55LtHD%3G1KYJ@R%0meFPq zm*PeO2DE?u_{@9*T2Y0?O$4jv$JEQ^_q_wvKeBLCxn!wX2P)`dQo^f) zj2juoBCHY6p(w-NENtQNUAzb#Ao>ILx4lfc;j;@=;+QQJ(%NgzhMAvKo;yIfzx^a>l4ua`Kvjc0KnF#y!WhU1QC(B zR6avMF2Fp0sCNfgCTq>J6j$Y#B|b9MZ1`E65$3qjeFEOYSxZ>La}sl7s3oQ8ZnGt~NLu%<9 zrf)+Enn-If^I*mykh)_AQ6dNR={JKsPL9ATEN&oA;T{&w)rXUkk%AS;W*%>akLk^F z&wTGF60A5baP>(SM>||MrL*uGPte8R5pxLssGEDVQm#{B6f%Om&EaHrqbE|qnxaBK zj(CKyHy3rM?G&`I+f@CizK~MM92xa=qd;aK#(zUkK7!SEwiYfQxg%(gStW)nuhngApu z?>a>$U$i9#aJIr6$@EB3dM=x0%l7jGTYW2bXy!qnat{v8V6$E9s46L2PnFP2@wkis z%g>8#bpq7Tm8p_NnM6`+>>9eR$HALP%&|nn=+*$mFnXqjD(&&X$#T}_*Hcv(4NTHSASYlA3^u+ zqXzq|^}&%ve@YI1m(Y8$a*2D1$6$LeFXFWbC%B_T{#f<{? z285J6NW*aFU@ky@H?t-}#{yVFX@O1;RHCt;b{fn-PwS{KVUym!^+9idSWU*xC)_G{ z_53I@(I#PU*=FL~D)Vz)Xd~xgc>tL6{Z=IM+%w|t_<>sf>al20>!(bxbu4CMQ$;Q0 z_1|7j3a22Z5nOYw-n)$@i9kN6m9l`|FZWkEeu)S%%ZWvl#*^2BrYLIJK3ry_^oqRr zw;|CUF9edc8(f|{w{HKxKO&!D%uEGsVz-ZfLCXIJ6bw-aj2gVQn4Hh8JG~9-{yu&I z8(Y)$a+X^obSo+SD?!DDgJBjnSiJw)9pmK+&5}Sr3H+g2G%LCj&|@q&#L?AUGd=ekox#iDirFyZVS1cd0R+A zn!bY;8fL&(ZY`S3z6La`3U?u(4HNCb+Tcyiy<`KNe@?Cd09I{<#Ms#XZh8B6IDGnH z7-cGv`R%j(*JB}JEbtWn-&g(rA1lch^RO-!0CLg222ol)eyY;A4_IJeeLSR6g5y$v z26pTQ^iH5Yvqk#<+WYQ*F8lX=NktMuW)iookh15CG9o)8d!(|n$)+MiM0R9^Y}xCT zWMpP#&y4K7*Y~`-@7&$@`~C;MkH@Eoc#i#fzg@9$Op{o2#-w%!nU zQ!M1kf@H~_pU=6#w7VsW{HmVEh1OUBp7i@=w$lddXnBoVxXmuuW~lH%q34CvomBMi$eU&s(PgR?|&t5`1{2gVaE)U^7=;r;pY5l!y;P( z`WvMZYoq?f-VZ4wHK9VD+V;KT)NWg&bCira*G zqdCO6qFLBf?itReZStxFtUZjtjv^HBI32LWVOyPSeg!3W19!g}(QSK3x>gXM55NXk zO}}LXBeo%dLL2I7cR$=$c$a!%Uln~j;;QI~Zooc_KfK*nXilj~H8q;;pV~&kqACTY z!#MnR;(}V=&^ju_mSh$Uyxm|Mt5e|m9*N94;4Xq{9e|u>t<{!o)^-b z_F^=1WJRwuuv~N5dUUtar37hix0gHFAXCOC;G7^1*z8o64+D1-i5(UHv;S~wiP3QH zaTM7aIo=DLg$aOk!x0>pchTXR{_JdMK5%I>v>9AHJZ5163VTmMkNe^N1ZY!E3*W&m z@^+%RwvWiZV4m-dPNkbW8}lr%+0ObUTUX&c(tu0}=)Y2(5}zhB&J%f=+JZBSuf{`l zSL{XPV4ar-hZ%4LCFKJoZvxQBz#IwBBy$Zz_x+FiIOv7{uz(4%Uwk@i75CdJ{qxjd z#`Me(^jl}yvj8^`JH!CQY1#k{dYSip{0=RAQ|fO{huQ~RjC0#bQyy(v0jsIW&exwd zRMu=ux3m?`3Zzljl%~cixAiu#TrC1+M!y>r7 z*8F_!y4BdtMzvtxkc$pip}g?1N<0KZgHIr?`%;KtWfM<@{9d)#9qetZZidLPS($L? z??PKSXF=K3M)9O8f)N>4mw~~_`~Z}Td%s|c)ad4oAfDlcYkx(+d47_ zkD0zlQNOS1J2FinKNqryM)SNcmkWb-Q749_SeP#hgjP{0;&+qmj=aS*Q{WE6l^dz7 z<|5}di&%dvmI<1^ z`br~v^pCPGRm~Ex4LWI_bh-x7mg88$ezK)dF`b}U0G;&kO10QB=+y2zk$IEebl;g~ zNNGcVLuUs`a7Oij)=x){PRqOUyFI+Pr+hfX9G}qy*mF^I;ZY0r?6mKGTyY&tvRN17 zcw&ZaF|#~ZUi^kxhxXz=>Yl7Dt7ai*n=)PK{2g_SO^CAG1O1uw^;K3rZ>aQzqz2F(bUU|?Ip+C^}OyZfQ8#C!W zF-8g9VquD4vk9=wncdl3wA@DIW)q`65;~eg@FrXs4=ZejF&njgpMA&)lC9k3WBIuV z%DDUlex!f3XC$7D{Zn-Qzj??BF`6l{TvAJU-q9zVv2$RU%M~m;f8NVR|1B9UZ9)(< zW1am6&YYeO>_e#!<|w#qPlRhy_u-|03qUJ)V2dxnM!|o;(6=cz0=dN-RX3=`J{-8* z1Z;F&EO$s!F7q6%dEN7HU?}8Oc4E>o?t&atV+fIpj{||cX+?>yzKRH;?>-4ZmiqRv~dkb)}w~|SxbzyUMBSP1y(t~E`NBdUi98{ScrWhzFw~M)AaOsW@6KBtPJ_YX_xs{W<}W-*3yOWmmyhC; zUNsHstz&g@OUzGaw7*g=)H5s^Y1*{7Y*q`O6AOE|xCNKeSUt^^-Srf&{ZSApC1g|w zY5$EsbQ51sK#!H6;L=MTWoA-5UY{Bbl zo*s+g}|RMD_?duWPWz`f=1FvI&Nf5A#N`IG)U6?gtB$2jDu?- z@>l*yF!z!g0rfD>XT^di1UJXti$D26>zHd!684-UL#LvTHu{p=Gol^*l=ddB0l9(7 zovqWfT6IAeEd>dL%Asy+d%ECNuQH5&Ob)|Ubg8-nCb%pH)Df6;H!_DcuPTDbmpV}9 zO{9h%Rtlkh#!zdBMxEq^?ksHqM$Jw+wgd+m6C%P!skFAw^_oQ%u|Eu)+T%r!Q(Zfv zv4CM5Be5llG+O!h%2Y}YqwO_&`I46zber#s5N4%OXJ3P+HT5uHT$Z^y@xOR5c z^!-7#o`%~QIf6~;4Ru2=F6O!~A>H4e%7$kUYZmc85Fj+z3JS;=>FeE(1jOg*n0FCT zQkye~l2kJQ7!|c@orTsD$@(M-JJl{`PPB*Pb4Ej5ZYIrPiS|r3Dn`VfNaIfKgUMZ= zhj^lnefh?hpZN55*UZmB0jiut-Tmw@8_-f^5$DD!Cb6|Zk zmiXb)54z-)uJw_7pPt~@FXVT~eK5bfkHWIK`$x}1ns!Q^Hs7TU9DCBzoCJ~a-;3*` zm-FWZv!JIFb6?u!aP9V|Juz(8NYh*(W#El1P+sP#w*-%?iS_A@I@wtMF5|USWq<6H z!n1Ou>NXTk~Srd2{g$Dw;Ryq+~QyRt$(ql}~-E^1{nFEpnVW-M+XG22s zmsbn|+VxFB`)eI?PYoK?aQ))vK0ha7m9OcbVYiq9^JhB>J`*F@RbrHAiS<(812iH8 zyp^tY+SDl9EGYbnN1A(;=kZfJ8F~W1k`y>qi&&?P=uLoGuQ7Vuu&Ew9`Oq3)L0-Bbfqyab}IKmKlCuq^ld_Jx@J+<#CM9FeEWHg zsXA`36E3SXp&YYa7LI-ZL`xS%(z=?}Z#6q!)^3uSS7vL7U_w1gA;lX6o?OLwbU6U?qa`s*uUv* z9>%OP0OeFrhp03&apEV4DGP|2Pb!*XaF&z*+sY>~tM-!nEW|hN)x^+z1ztIRmCGlA znP#&Dvxs9ig|G+Gn3y!#KQWN_b;*4mMDzyT4M8_Z$@9xQIe<&>Su|&JVy_UK&CZJD z$tRQeakX~?BFRx4-btO<3Ax0^kHnx-i5C>TTU`b<#z{rWvp8joG!&#J2?`kw%)dG+ zp9!`WnJGCKB91DLp8y0&1jduG!O@gb;d5rxBd`3kC#!d8%H!|e+J|g=a|N1+(jYpx z2b~T%&8;h17x(q#dQ6DZ=KycKPe{P_YFfB9fSXJDE*KlBjP=M|@4j7kUX9v6tvObp zyH+zr?n2v-MZLDN&Xrre2Kp#<$yAJ(zMJD@ug^fZo6 z3X4sgoU>p%CR}uE>c-)0?7#JBg9fW8zJqn6T=e@LDa|L#NJe9yrErZ*u?bE4*T)jb$1AyT+x%W+BAW{8 zwsO#{w1ayIA9NE}-LDyO9={S;3?y4*tRrg(nF~RMkYVi^#cT^jOH)HtiNRd*U$wNS z;3eSb$+Hpr{O-UCi}aH3m^LTdsx&1EPdiCo4t!TXeE<4%&WqgiPC+?HS(6I|aVW;m z{)(HZA;7_6c*6aT|9)CP!Cp^)%#r*Mct$0237_&a&r=?mtg<2ODG(Dk!hpCt`nC0* zN2pAOF3{b&*)2EzbgEfaIPnYvgTC+9P0>3?_?3bv4yQ?Hs#o9@hwArA$$t5!-E0mQ za*U3?Sox(KtD%60Lu8P8YKSxRDTbZH15DPYl$$@-UVp!J^r!~T z!P@jJF;-0aKt*u9;Nq-m5Z=_CU~ffON4(59iZ zgLof-txX8Di$ByS0EzB;+cp%==koD9ZK3=P1!5YX(iEiiuYmU=oX&VZ;J95Qo#+}e zw#o?HMxK}YMBv>AFoCJi1**`DL6~)$)nhGqv@!pi1&KoG)%cO*6222Xwh-!vy6kev zUf{$uSpT1F|E2uJt{DHpxvkM>BxyG70uu2ndF0yQt$l1CP8B zjvuIg?_8cYYRAS}0AS`e6kn^Ic@R9ZlHQdNp#o0X|Q;bF|=xIf*zl6|VGyQhOe`C$O#{807OXPLQ z`%Mv-z=_q5B}9e#rg8w6i;$mbYVq>@Pdo#4aM;S`BTR$p-n)w;;JZ-^5ZzwN$9I^< zn}ZJFNJ&F$QWrq3e6OEC7oZXEkpn5#AB(tJ?&_+4JeRK9zY6-sG7IrR`B68T1H_*6 zvY5}}t zX5SJqW)-U7YZSR`Tc^jX5@!Kd#y(5b`(&2IU}>Q)gk>K6Pfrpko5z}*q_WBe zTZ@yKKqc&JNX@o>IpwfsdT0TVv$aX`=!XGt+nI;9&iF#*u7%I`Th~y<+2bjgItnd| zwnRikJ>Q0 zwlW8R80l@@U9lr?xDX z3vmVFl)dxD+%#uGZ!K&fff9HHd3}RNLv70=m+*>)!Gn^r5r~-8z2Xbr435T~PG*sC zYG^t`oUs`%mzdIUb9B>TL}scEA_k~Asi45nme(d=Z$~OE>VX>sG3yRIs*K-$nD|(Y zyg`)}qaS540x$uJ`di3mTHU$sN< z13urp5-FXSD_Q2)6$G{-V4oUKhJ`Aiyc*0?-+2M3WQ_n1oo}%R1E-hIhjc#PSYx6M zLeh>D+_&Nl8#7&vJIW%1G$L}LXXWmf9QSks9H8*W=p!N>PCVSS$iVKR@F&^q=^F%> zb9TSCTU=UsZ~4gVx^Gjh50UUT9}m>NqkTJ1QgyXj(J%v7n8h4d@uJZft>2}MF)FO> zM`E0%I~Zj^aDMV(5W<&*p&ZFeMJaPhS|ckD>xYLh8Tz(>+IezcL5W@A74((908?+V zT&4Se_j706Pdtebz51I$I;1GyNIfCRA1vhu;$BDT0I&qF;QPM}Q{xBD^aRA{5SX(Q zWqGakSkOp~KdHY4NfMsSJeOH+{?c>A=8H3`WA7TGVYx)c4CCxvh>`MEU@pBL+pQXqQK)vDGhM`NyT zB5=usi{MK(FnuqiKlL={I@ei90AR@5?0lGB`UTF^Y5Wso^WfjZQ0;>s4%vwBV{F9y z$>?jmXo7H_XvuB+PT?xQbX|)iiYM)mRtkrNPdn0u5m7&UQjppu_Nkqo)VqEgtZI9` zY>V%YVtG<^GjVOt61S+i>n&$|+P<|RR0RCg?D{c^=T{*8H|-Us@g;ihpAqw&h+^C9 zQ^}6#R51g${4ZF9K$2$X?By)1)qfN`@gIMlX9+{O#vi;KpWT7rm~R8KB!Ojt8LU>} zB~BVeRPZ{dzLhtZ5PFUD?k$p;w6xo>ZC<#h4c`2ECLxqC){k+-pRKf>*0U?`hV7`x zvcWwC-qEw4Z~cKCmInS<_xOi8H$td*0NYD&LE1fkz$$w?pDgcMGzxAt#v+B)65K4l_j7XBADxAGj0b(d0&zuX`H?8Ktd za1c+H&kevsN-jwD@4u_l?klk#9tNCg7RPB?M`QD6*UNc*9@iwp@fCT&`*BMHkV=_y zxIE~^wZ!5;bmAWa*?RVzI;r1>%pi(===so1Nb`F{Jcb-2iq{4D9Fck%xLEI0WIi3E zy?!o1q8f+REvunMG5MaZa2dS?|39 zu}L!OCb5jzMb)bFovJrcOxYBnv{EsLF0T$thRQ0+oQqiJ3-@KMg+N&rd3~y=h;ns) zsTpYe?Yh_3v9JkfP#zyOu(64=Peif(`B#i%n9;9M&U&-(%4WPe>}_@XwtS8-DO$k6 zA~TxT%Al^|fQ`18B#k^u9?SL=Gq}mWFCt~t;8ge!Ma1h>LrCoJQWKmIAL%e0xNHGl z-m;Q*<0-6^-N`UKs%xiSp3<|5C962Wlz>BZt?*QKbXfhoH#PX;bLI4~vP!a_mD`)Z~MJ~rGm42u>INR z)}lfF14l(}%G<$ekIki%aGxXYJr46j2dADwV0)Jrsa*;ax=K&_mz{|A8SA&hJbnjR zxOL~YJ*^$nQpe@7Z|I^8m;U_%HF*zs2uDu?xyW(Cy~4_ZFB4!sqU0qV9DXUBs;mUd z#s>Zt^?@0Wm40R#K`PC zr>Z-bn)SWbX6Loeg@*Uz{1P}Pzs1!7L=h`PAQ&D>v0aeuYF?LfBhs?Nim|dS1xwoI zi%hIcd>OexW)Md$P`7l47a>n|DL{aubf+%@u`(z$*9MHXSLhGZ>fLr-bk=2K>9xVx zn92*`4acxxWBH_MzWauAxZ~=gromY-;M3ceyB*74;8xUdk$wfdeQj`Pr$P)%6B{o$ z3@G+LbH`zuI>(v4`UVOdwloR;K5o+GeI~xl+08j0kv;u=nB=fj-8^3)T)SCl78P;P zX*~E?o$sc}fp+M~u7~+<897>@fsE3!u3_cT(|<1S_ zC)=W*fvsIVf~fnn0>&L}xG>nDK-F;4iAzD3+a>+j9(H>;F)80rvgNd0<^2A$G0N7n z-q;b@K}zky<9RFmb!9chR)PR<@_Q{U$6Qu$f$V-V&q}|sB%^136aQ56-pSL%lF^95 zfDf~Rp47^8AVP*LysNqSYNlcD*KEVHZQNd)^pbYzvb(qLZbvuPK3fkWYU36*qPKN^ zbt%qA^X{=Yx{t!@gp6!sr~kF}Q64Cn_!N{Ck*yy|kgJ-p1cB4`%0$UHMhlcsHadX) zbhxNf8LqDarBdy9-@a@r4sqT7!;9&XbU(P&nVeqC`b~tyafi#clyc+8sb3OuKiDfb z>&**9S$Chkkzs~^Pf}q=XwgX?O}BP!*i8W6`a8^Ae(%{T8ihA)e@j$J%|T?N$53dU zWm@pPRRq2&trR88<5Q-TRl8dytm-*5B2c<}<7uLKkWT)7;?1J22Jf>uXYqi*P_D(D z(})ieC;otTXEhc-O|)bz67n!S&w3JGP-FWU|9);6vuBv_Lhe&ol2F>zytAvY&?>6M zXniDZMoqeHA`kQF-@LigPL_0zcOlIjr|I3+nLD2zK-HEV=h=rhp)+3b!l|~$sK#`j z!pTX71|4?2xF04P7ipq(W?CRa<^;GpilGEc&w2XV!{~Z^?RJGTeObmiP+N1S9H*uW zUj<&h#;UB(C@MK4LEcDw2PMnD5JvLd7{o&t>?mgvu%0Ws49lDj!&{eXy#!wX7O51% zwu7jm_))OZGsKC3apzoQ>g`0Gdfy=%Daw79Hxx%HIvV6UXP7qbDF-b^%~Gfwkx3jT zBOj7v)E8T4jXq)rT4Z1tv#;(pTe`gha(oDJ^!e9RO=%fq@_-=BCeL2(xLir}*UrdU zK7r-ObI|(n%-@eMA4~eZM`_4bsIuHGqr{SL4gIR#g|A>(T2jcX!p!@QajyrOi~%N3 z8^@9}>d4Cn_#(-%73!@IS)9~EABK59;HHEeBnp?CHAGbIbY;JTjMM7-?OJ7=KbNan zLvQ3z$M}Pr9lPYO@0){zdoysX8$5VziQG;oGobVgu|r?%D}5O*&k%H;t97h=aPH?? zk22?UJ&KKRB1Hc7KfC+mGeQE!p{p%##Qx)l7@qnpGzx-d?wpq;{`1FpbTkU(`Y}RB zfk%%FTgz!8Y#R2kG@Omnu&Z1L$uiK!vXR&5E5=B&rGP%VkbSFloj%rjFm!>h)k#jM zC4wVys*dj=x`l9cF$&MJrM13{cvs*CryUq z-0`b}KWe28+NqpiTPNCo_S*=+yKqw%f}rWFAgCR^U22Wasc7R$h1qB;n(TyDR<0sOb%b|=ysxmQ5h!>!1_sf z_y=@x((9mmUQuvu6Ve=eKl!3-FjA8^t_lH|6x9kVw`$nsI5s}KSK z_%>ojgbFmo(k}~>(zhCW&hU=3a_OltK=tzANBp4KcrRUd|Gnnwn^}V{E3DK_NHaJA zkK(kS>sc#8?`IAlOvTv9;hhCMe+YRO?Wo&Ctnu*gxPiGvN~`OF4O5^yu*PPc##wbL zU7Uo_5S>oW=qM|@%qYi6=W6VL7E~JA@OF~B0GC~sh4cEw4z#}M#nJWNRP^oIpHr9! z5oKg!hrrNs;0(pIm_f3QvOy(>MLxux{+VqU-l|}ExSs7U3$jINelT8c2f?UnoDF;j z9_y6D6V~h3cw^ETk4ExfK#&U%Y`R+ED8KOKnGKF!;f%CLzM;pty=J5D z#XC-onnOzc;UmV9(Z!5>&sMjVzpvWF?GEgD;=9BLIv~kb$ZFBIu&$4$YtQ{o;GXZ~ z0Hd(ItW6MCjA~)FmY5ZW%ZzZb1C`i)E%9PAeUA37HhB79*q44Yq~ZRVP_mORe8i#> z(#REEv7~A-M z&IQI?O`apjs*8BgtChpeR5i+vPGu22e5}J=-MAc(C#s+6ANS>y$X3&2tMbQHeyh)91hDGX4bV_}gsz52oIbhpmnq7#;ozv9AqM#LX;wgTp9 z*{`9&>vt8L%ff=d92b%vgB;W{a?AV{cg_24)9UgJO1^F45%bJXwZ;v%RfhX-psYHC zz24JXTG{ljZ-t}x=q*1qbC-;tZ#g{JL~EKi%*^rEUEKd6nOW)>bk${6b68`x;j-5{ z|C_R8eE@7kxvjj4%NLe;4W<+-Ry(l& zDpa#|Fe|xOC2%tA*MelHO2g`}Q%&p+AG-P7A)`!ifkaB49u*_J8rj-e!rdCcc|N$E zj{B3TbW+gPl8;DC1M}1!ug}x{!w2@V-OCFO=rZGWD=o0FZf2^0n0QB3t!M$-kxt%G z5^j@>P(Hh+53}fQHxM&%4($$Y7S6={Jl2rAwI$7o)OH{(IEqkMJ0!j@CKFuXp67~W z%@Wj<_|}}!{V(csHQTw82rjorg3(e0fH??VHS7?g{O=R2kN`ER8<@V6OwwR==UY@&Pk4NV>a)H^$=WL zxgd$+8{%8JSjRBLVaZVvmAUUX8g&n> z`+#DsMAWq4ltWEfTWdvFAGi!E|CYd3sA|-_yXJ3zuJ~HmKvlu}@yl}FC(P;UDJe1K zAk2qxo@2s9)2pETRJsUV7PD{C@NqBsqioI8)mIo()Jv$2O#xr!E!tw{D5f0fqT+kh zJbwjSkB{T%oOCE~{o*`OpxgU{6>*YB&ccOacYp%yv^Fbz zX{PgyJ4}`~1ctZe@W_y%;;zw|;j`Fc2&Qj$Vii&UEuoN z0{?lbQt(G=hlBi$wA+lT0K?HP8H6*xtSpuOD5LqBjY<;pJ(sRp7KWW<&l23h+Ww_ z8>-$+75DBYML=G!HkT_zttb=8UnlXeHxpR^ZaU9o`U|4ZUv20}V_di9A4dir4$GnU zCfIH6UeXjXx>3?snQ_m&3mnVyHdxbjRy|KqM>L)u6$I0NE$-|_dd4Wos3TmQZP-zoD`{jC|2j666fm4l?4hWt*m2 zftn%)kQAhMcA#ZVFa?;#1ZnxmiIODu)cppN*>X@QPMi~L0oh5mosr!mHYPsnyT@W- zG`$At{umMc5PDp-g`QVyxFX|ZRu;mEV4G%J`B?|o9ENsvmtaq|}Xh#26kY^jPc{EY6}Ikwk#Tz{w>WfZ?IG&4S4KgY-xo!O;ls5t*P zz{5@KtDm-F9G(ubr>=p+?;AM|hrnYbfa(yf$n>{IeEojwZBe!o9{ zF0lFg*r4PKiZJPTN7pl&b=Zx0k9oxd$Cj>Cjh8y<4WB~Vgg{zku7F)>ImnzIK3hIE zg$#Q9_F_qcCzgN_Gq|H{&r1Jp4CY@2*#QHM!k!53gQGi*4*ZydLu|=^@4mDL3aYhT z>OZTQ1x)S_vkM8YkAl(f7n%WZw4Gl~+(?A17-D(bLzKG?lHi^ z@+*qCSU~!BKst&{03bNPZ7r~w{O3*O)WDOmx#{|}miQ{(^u literal 71622 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 QI|KhTRCJXq6zwAa7fi^U1poj5 diff --git a/examples/parse-schema.js b/examples/parse-schema.js index 42e1e8a..2cfac2e 100644 --- a/examples/parse-schema.js +++ b/examples/parse-schema.js @@ -4,7 +4,7 @@ var connect = require('mongodb'); connect('mongodb://localhost:27017/test', function(err, db){ if(err) return console.error(err); - parseSchema('test', db.collection('test').find(), function(err, schema){ + parseSchema('test.test', db.collection('test').find(), function(err, schema){ if(err) return console.error(err); console.log(JSON.stringify(schema, null, 2)); diff --git a/lib/field-collection.js b/lib/field-collection.js index 608e5b0..86399e4 100644 --- a/lib/field-collection.js +++ b/lib/field-collection.js @@ -2,13 +2,12 @@ var Collection = require('ampersand-collection'); var lodashMixin = require('ampersand-collection-lodash-mixin'); var parentMixin = require('./collection-parent-mixin'); var Field = require('./field'); -var debug = require('debug')('mongodb-schema:field-collection'); /** * Container for a list of Fields. */ var FieldCollection = Collection.extend(lodashMixin, parentMixin, { - namespace: 'FieldCollection', + modelType: 'FieldCollection', mainIndex: 'name', model: Field, comparator: function (a, b) { diff --git a/lib/field.js b/lib/field.js index 8f0bc3c..941bd8d 100644 --- a/lib/field.js +++ b/lib/field.js @@ -1,13 +1,12 @@ var State = require('ampersand-state'); var TypeCollection = require('./type-collection'); var _ = require('lodash'); -var debug = require('debug')('mongodb-schema:field'); /** * Describes a single field in the schema based on sampled values. */ module.exports = State.extend({ - namespace: 'Field', + modelType: 'Field', idAttribute: 'name', props: { /** @@ -24,13 +23,6 @@ module.exports = State.extend({ type: 'number', default: 0 }, - /** - * Number of counts of all children types, including Undefined - */ - total_count: { - type: 'number', - default: 0 - }, /** * If using shortened keys to save space, it is expected this be the "real" * name of the field that could be input by the user. For example, @@ -56,7 +48,17 @@ module.exports = State.extend({ description: 'string', }, session: { - parent: 'state' + /** + * making parent a 'state' session variable so that its events get passed through + */ + parent: 'state', + /** + * Number of counts of all children types, including Undefined. + */ + total_count: { + type: 'number', + default: 0 + } }, derived: { /** @@ -85,8 +87,10 @@ module.exports = State.extend({ }, /** * How many unique values. Not using cached property here - * @see Type#unique. - * @returns {Boolean} + * because it depends on Type#unique which is also not + * cached to avoid excessive recalculations during parsing. + * @see Type#unique + * @returns {Number} */ unique: { cache: false, @@ -96,25 +100,28 @@ module.exports = State.extend({ }, /** * Does this field contain any duplicate values? - * Not using cached property here, @see Type#unique. + * Not using cached property here because it depends on + * Type#unique which is also not cached to avoid excessive + * recalculations during parsing. + * @see Type#unique * @returns {Boolean} */ has_duplicates: { cache: false, fn: function() { - return this.unique < this.total_count; + return this.unique < this.count; } }, /** * Convenience alias to access sub-fields. Returns - * null if this Field does not have a 'Document' type. + * undefined if this Field does not have a 'Document' type. * @returns {FieldCollection} */ fields: { deps: ['types.length'], fn: function() { var objType = this.types.get('Document'); - return objType ? objType.fields : null; + return objType ? objType.fields : undefined; } } }, @@ -130,6 +137,9 @@ module.exports = State.extend({ derived: true }, true); res.types = this.types.serialize(); + if (this.fields) { + res.fields = this.fields.serialize(); + } return res; - }, + } }); diff --git a/lib/index.js b/lib/index.js index 18f4b06..545244e 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,6 +1,5 @@ var Schema = require('./schema'); var es = require('event-stream'); -var debug = require('debug')('mongodb-schema:lib'); /** * Convenience shortcut for parsing schemas. @@ -15,10 +14,13 @@ module.exports = function(ns, docs, fn) { }); var src; + // MongoDB Cursors if(docs.stream && (typeof docs.stream === 'function')) { src = docs.stream(); + // Streams } else if (docs.pipe && (typeof docs.pipe === 'function')) { src = docs; + // Arrays } else { src = es.readArray(docs); } diff --git a/lib/schema.js b/lib/schema.js index 2d97bbb..42eaab2 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -1,11 +1,12 @@ var es = require('event-stream'); -var Document = require('./types').Document; +var _ = require('lodash'); +var DocumentType = require('./types').Document; /** * The top level schema document, like a Document type * but with extra stream interface. */ -var Schema = Document.extend({ +var Schema = DocumentType.extend({ idAttribute: 'ns', props: { ns: { @@ -25,6 +26,15 @@ var Schema = Document.extend({ schema.trigger('end', this); }); return stream; + }, + serialize: function() { + var res = this.getAttributes({ + props: true, + derived: true + }, true); + res = _.omit(res, ['total_count', 'modelType', 'name']); + res.fields = this.fields.serialize(); + return res; } }); diff --git a/lib/type-collection.js b/lib/type-collection.js index 7b4bd21..8b4a077 100644 --- a/lib/type-collection.js +++ b/lib/type-collection.js @@ -5,7 +5,6 @@ var assert = require('assert'); var _ = require('lodash'); var Type = require('./types/type'); var types = require('./types'); -var debug = require('debug')('mongodb-schema:type-collection'); /** * Helper function to get the type name given a value @@ -26,7 +25,7 @@ var getTypeName = function (value) { module.exports = Collection.extend(lodashMixin, parentMixin, { - namespace: 'TypeCollection', + modelType: 'TypeCollection', mainIndex: 'name', /** * Sort by probability descending, with Undefined always last. diff --git a/lib/types/array.js b/lib/types/array.js index 5a09da3..0a4bacf 100644 --- a/lib/types/array.js +++ b/lib/types/array.js @@ -58,5 +58,17 @@ module.exports.Array = Type.extend({ }, collections: { types: TypeCollection + }, + serialize: function() { + var res = this.getAttributes({ + props: true, + derived: true + }, true); + res = _.omit(res, ['total_count', 'modelType']); + res.types = this.types.serialize(); + if (this.fields) { + res.fields = this.fields.serialize(); + } + return res; } }); diff --git a/lib/types/constant.js b/lib/types/constant.js index 90d2858..9ed44e1 100644 --- a/lib/types/constant.js +++ b/lib/types/constant.js @@ -28,6 +28,14 @@ module.exports.Undefined = ConstantType.extend({ name: { default: 'Undefined' } + }, + derived: { + unique: { + fn: function () { + // undefined does not count as a value + return 0; + } + } } }); diff --git a/lib/types/type.js b/lib/types/type.js index c46355e..26ae074 100644 --- a/lib/types/type.js +++ b/lib/types/type.js @@ -1,3 +1,4 @@ +var _ = require('lodash'); var AmpersandState = require('ampersand-state'); /** * Generic Type superclass has name, count, probability properties @@ -17,7 +18,7 @@ module.exports = AmpersandState.extend({ parent: 'state' }, derived: { - namespace: { + modelType: { fn: function () { return this.name; } @@ -25,12 +26,23 @@ module.exports = AmpersandState.extend({ probability: { deps: ['count', 'parent.count', 'parent.total_count'], fn: function () { - if (!this.parent) return null; + if (!this.parent) return undefined; return this.count / (this.parent.total_count || this.parent.count); } }, }, parse: function() { this.count += 1; + }, + serialize: function() { + var res = this.getAttributes({ + props: true, + derived: true + }, true); + if (this.values) { + res.values = this.values.serialize(); + } + res = _.omit(res, 'modelType'); + return res; } }); diff --git a/lib/value-collection.js b/lib/value-collection.js index acf5d71..3262961 100644 --- a/lib/value-collection.js +++ b/lib/value-collection.js @@ -3,8 +3,13 @@ var lodashMixin = require('ampersand-collection-lodash-mixin'); var parentMixin = require('./collection-parent-mixin'); var Value = require('./value'); +/** + * Value Collection, stores any values wrapped in `Value` state + * and serializes back to its pure array form. + * @see Value + */ module.exports = Collection.extend(lodashMixin, parentMixin, { - namespace: 'ValueCollection', + modelType: 'ValueCollection', mainIndex: 'id', model: Value, serialize: function() { diff --git a/lib/value.js b/lib/value.js index 8871fd2..f3b77e4 100644 --- a/lib/value.js +++ b/lib/value.js @@ -1,7 +1,10 @@ var State = require('ampersand-state'); +/** + * Value, wrapper for any value found in documents. + */ module.exports = State.extend({ - namespace: 'Value', + modelType: 'Value', idAttribute: 'id', props: { id: { diff --git a/test/basic-unique.test.js b/test/basic-unique.test.js index 3456312..41aa470 100644 --- a/test/basic-unique.test.js +++ b/test/basic-unique.test.js @@ -5,12 +5,14 @@ describe('unique', function() { var docs = [ { _id: 1, - registered: true + registered: true, + b: false }, { _id: 2, registered: true, - code: null + code: null, + b: 'false' }, { _id: 3, @@ -50,14 +52,22 @@ describe('unique', function() { assert.equal(schema.fields.get('registered').types.get('Boolean').unique, 1); }); - it('should have unique of 2 for `registered` overall', function() { - assert.equal(schema.fields.get('registered').unique, 2); + it('should have unique of 1 for `registered` overall', function() { + assert.equal(schema.fields.get('registered').unique, 1); + }); + + it('should return unique of 0 for Undefined type', function () { + assert.equal(schema.fields.get('registered').types.get('Undefined').unique, 0); }); it('should have unique of 1 for `code`', function() { assert.equal(schema.fields.get('code').types.get('Null').unique, 1); }); + it('should not have duplicate values for b', function() { + assert.equal(schema.fields.get('b').has_duplicates, false); + }); + it('should have duplicates for `registered`', function() { assert.equal(schema.fields.get('registered').has_duplicates, true); }); diff --git a/test/type.test.js b/test/type.test.js index a028273..66ad474 100644 --- a/test/type.test.js +++ b/test/type.test.js @@ -11,8 +11,8 @@ describe('Array', function () { assert.ok(arr); }); - it('should return Array as its namespace', function () { - assert.equal(arr.getNamespace(), 'Array'); + it('should return Array as its modelType', function () { + assert.equal(arr.getType(), 'Array'); }); it('should add values of a single type to the correct type', function () { From 4096b352d7e864545fb37accc594a69d50514b21 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Tue, 30 Jun 2015 14:01:52 +1000 Subject: [PATCH 34/42] updated diagram, some properties missing / renamed --- docs/mongodb-schema_diagram.png | Bin 141430 -> 145225 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/mongodb-schema_diagram.png b/docs/mongodb-schema_diagram.png index eba84a3c6ca83097ed4a63dd50515f5ea8d6c56e..134b8292344637184867ef4db4a3b402ea70cc78 100644 GIT binary patch literal 145225 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 fh*y3-XntcHf|`rQke|x3 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


=;0mk~gKq_^dGhsVuVA~+ZJ_5^B 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π*mXAYfc~aGA-t3g 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 X%ig)VM4H&`*Qgj}SGh(41ZQvN! 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
jP+SPJ>9FV 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 From 55150d377eefdc4b19c6472bd3dcfbac25863788 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Tue, 30 Jun 2015 20:41:03 +1000 Subject: [PATCH 35/42] removed session parent again, causes circular event triggers. --- lib/field.js | 6 +----- lib/types/type.js | 5 +---- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/lib/field.js b/lib/field.js index 941bd8d..5a98315 100644 --- a/lib/field.js +++ b/lib/field.js @@ -48,10 +48,6 @@ module.exports = State.extend({ description: 'string', }, session: { - /** - * making parent a 'state' session variable so that its events get passed through - */ - parent: 'state', /** * Number of counts of all children types, including Undefined. */ @@ -79,7 +75,7 @@ module.exports = State.extend({ } }, probability: { - deps: ['count', 'parent.count'], + cache: false, fn: function () { if (!this.parent) return null; return this.count / this.parent.count; diff --git a/lib/types/type.js b/lib/types/type.js index 26ae074..536e6e1 100644 --- a/lib/types/type.js +++ b/lib/types/type.js @@ -14,9 +14,6 @@ module.exports = AmpersandState.extend({ default: 0 } }, - session: { - parent: 'state' - }, derived: { modelType: { fn: function () { @@ -24,7 +21,7 @@ module.exports = AmpersandState.extend({ } }, probability: { - deps: ['count', 'parent.count', 'parent.total_count'], + cache: false, fn: function () { if (!this.parent) return undefined; return this.count / (this.parent.total_count || this.parent.count); From 264d0ef928b41f008127af83413dc6f0d42bb396 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Wed, 1 Jul 2015 19:20:13 +0900 Subject: [PATCH 36/42] added Field#arrayFields alias. more tests. change:types.length has to be triggered AFTER the new value was parsed. --- lib/field.js | 7 +++++++ lib/type-collection.js | 4 +++- lib/types/array.js | 8 ++++---- test/array.test.js | 29 +++++++++++++++++++++++++++++ test/field.test.js | 18 +++++++++++++++++- 5 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 test/array.test.js diff --git a/lib/field.js b/lib/field.js index 5a98315..0a15b34 100644 --- a/lib/field.js +++ b/lib/field.js @@ -119,6 +119,13 @@ module.exports = State.extend({ var objType = this.types.get('Document'); return objType ? objType.fields : undefined; } + }, + arrayFields: { + deps: ['types.length'], + fn: function() { + var arrType = this.types.get('Array'); + return arrType ? arrType.fields : undefined; + } } }, collections: { diff --git a/lib/type-collection.js b/lib/type-collection.js index 8b4a077..40156c7 100644 --- a/lib/type-collection.js +++ b/lib/type-collection.js @@ -53,6 +53,7 @@ module.exports = Collection.extend(lodashMixin, parentMixin, { * @param {Any} value value to be added */ addToType: function(value) { + var newTypeAdded = false; var typeName = getTypeName(value); // get or create type var type = this.get(typeName); @@ -60,10 +61,11 @@ module.exports = Collection.extend(lodashMixin, parentMixin, { type = this.add({ name: typeName }); - if (this.parent) this.parent.trigger('change:types.length'); + newTypeAdded = true; } // leave it to type to add the value type.parse(value); + if (newTypeAdded && this.parent) this.parent.trigger('change:types.length'); }, serialize: function() { this.sort(); diff --git a/lib/types/array.js b/lib/types/array.js index 0a4bacf..9a9a8f9 100644 --- a/lib/types/array.js +++ b/lib/types/array.js @@ -20,6 +20,9 @@ module.exports.Array = Type.extend({ } } }, + collections: { + types: TypeCollection + }, derived: { total_count: { cache: false, @@ -42,7 +45,7 @@ module.exports.Array = Type.extend({ deps: ['types.length'], fn: function() { var objType = this.types.get('Document'); - return objType ? objType.fields : null; + return objType ? objType.fields : undefined; } } }, @@ -56,9 +59,6 @@ module.exports.Array = Type.extend({ this.lengths.push(arr.length); this.count += 1; }, - collections: { - types: TypeCollection - }, serialize: function() { var res = this.getAttributes({ props: true, diff --git a/test/array.test.js b/test/array.test.js new file mode 100644 index 0000000..e4d35f2 --- /dev/null +++ b/test/array.test.js @@ -0,0 +1,29 @@ +var ArrayType = require('../lib/types').Array; +var assert = require('assert'); +var debug = require('debug')('mongodb-schema:test:array'); + + +describe('Array', function () { + var arr; + beforeEach(function () { + arr = new ArrayType(); + }); + + it('should be constructable', function () { + assert.ok(arr); + }); + + it('should trigger types.length events when adding a new type', function (done) { + arr.on('change:types.length', function () { + assert.equal(arr.types.length, 1); + done(); + }); + arr.types.addToType(15); + }); + + it('should update .fields alias correctly', function () { + assert.equal(arr.fields, null); + arr.types.addToType({foo: 1}); + assert.equal(arr.fields, arr.types.get('Document').fields); + }); +}); diff --git a/test/field.test.js b/test/field.test.js index aee1e67..4cb46a5 100644 --- a/test/field.test.js +++ b/test/field.test.js @@ -31,7 +31,15 @@ describe('Field', function () { assert.equal(field.type, undefined); }); - it('should trigger types.length events when adding a new type', function () { + it('should trigger change:types.length events when adding a new type', function (done) { + field.on('change:types.length', function () { + assert.equal(field.types.length, 1); + done(); + }); + field.types.addToType(15); + }); + + it('should update Field#type when adding more values', function () { field.types.addToType(15); assert.equal(field.type, 'Number'); field.types.addToType("sfo"); @@ -43,4 +51,12 @@ describe('Field', function () { field.types.addToType({foo: 1}); assert.equal(field.fields, field.types.get('Document').fields); }); + + it('should update .arrayFields alias correctly', function () { + assert.equal(field.arrayFields, null); + field.types.addToType([{foo: 1}]); + assert.equal(field.arrayFields, field.types.get('Array').fields); + assert.ok(field.arrayFields.get('foo')); + }); + }); From 8129ac849eec2ba4347251c9bd174a999ccb276b Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Wed, 1 Jul 2015 20:11:56 +0900 Subject: [PATCH 37/42] trigger change:probability events in all cases. --- lib/type-collection.js | 5 +++++ test/field-collection.test.js | 22 ++++++++++++++++++---- test/field.test.js | 1 - 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/lib/type-collection.js b/lib/type-collection.js index 40156c7..b3529b8 100644 --- a/lib/type-collection.js +++ b/lib/type-collection.js @@ -66,6 +66,11 @@ module.exports = Collection.extend(lodashMixin, parentMixin, { // leave it to type to add the value type.parse(value); if (newTypeAdded && this.parent) this.parent.trigger('change:types.length'); + + // trigger probability change event in all direct type children + this.each(function (type) { + type.trigger('change:probability'); + }); }, serialize: function() { this.sort(); diff --git a/test/field-collection.test.js b/test/field-collection.test.js index 1f1b927..cafd1cf 100644 --- a/test/field-collection.test.js +++ b/test/field-collection.test.js @@ -1,8 +1,6 @@ -var Document = require('../lib/types').Document; +var DocumentType = require('../lib/types').Document; var FieldCollection = require('../lib/field-collection'); -var _ = require('lodash'); var assert = require('assert'); -var debug = require('debug')('mongodb-schema:test:field-collection'); describe('FieldCollection', function () { var collection; @@ -18,8 +16,24 @@ describe('FieldCollection', function () { }); it('should pass down collection\'s parent to its values', function () { - var doc = new Document(); + var doc = new DocumentType(); doc.parse({foo: 1, bar: 1}); assert.equal(doc.fields.get('foo').parent, doc); }); + + it('should trigger change:probability events in unaffected children', function (done) { + collection.addToField('field', 16); + collection.addToField('field', 5); + collection.addToField('field', 'foo'); + collection.addToField('field', 'bar'); + var field = collection.get('field'); + assert.deepEqual(field.types.pluck('probability'), [0.5, 0.5]); + + field.types.get('Number').on('change:probability', function () { + assert.deepEqual(field.types.pluck('probability'), [0.4, 0.6]); + done(); + }); + collection.addToField('field', 'baz'); + }); + }); diff --git a/test/field.test.js b/test/field.test.js index 4cb46a5..8be7341 100644 --- a/test/field.test.js +++ b/test/field.test.js @@ -58,5 +58,4 @@ describe('Field', function () { assert.equal(field.arrayFields, field.types.get('Array').fields); assert.ok(field.arrayFields.get('foo')); }); - }); From 52f905a30dcb0339aea38e30677e0f56adc76d4e Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 2 Jul 2015 15:37:28 +0200 Subject: [PATCH 38/42] (FAILING) test to listen to data events. --- test/schema.test.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/schema.test.js b/test/schema.test.js index c96077c..10c7167 100644 --- a/test/schema.test.js +++ b/test/schema.test.js @@ -89,4 +89,20 @@ describe('Schema Helper', function() { done(); }); }); + + it('should trigger data events for each doc', function (done) { + var docs = [{foo: 1}, {bar: 1, foo: 2}]; + var src = es.readArray(docs); + var count = 0; + var schema = new Schema(); + src + .on('data', function (doc) { + debug('doc', doc); + count ++; + }) + .on('end', function () { + assert.equal(count, 2); + done(); + }); + }); }); From dd091e12c3a1bfee20afa4b45ee5c1c2a7dc7a18 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 2 Jul 2015 15:44:39 +0200 Subject: [PATCH 39/42] use schema.stream()'s end event instead --- lib/schema.js | 5 +---- test/schema.test.js | 6 +++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/schema.js b/lib/schema.js index 42eaab2..5d0ebb2 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -18,13 +18,10 @@ var Schema = DocumentType.extend({ }, stream: function() { var schema = this; - var stream = es.map(function(doc, done) { + return es.map(function(doc, done) { schema.parse(doc); done(); }); - stream.on('end', function () { - schema.trigger('end', this); - }); return stream; }, serialize: function() { diff --git a/test/schema.test.js b/test/schema.test.js index 10c7167..de96952 100644 --- a/test/schema.test.js +++ b/test/schema.test.js @@ -48,11 +48,11 @@ describe('Schema', function () { it('should trigger an `end` event at the end of parsing a stream', function (done) { var docs = [{foo: 1}, {bar: 1, foo: 1}]; var src = es.readArray(docs); - schema.on('end', function () { + var stream = src.pipe(schema.stream()); + stream.on('end', function () { + assert.equal(schema.count, 2); done(); }); - - src.pipe(schema.stream()); }); }); From a49f9fd7e188173e4ed45beb80fd41190c2d7602 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 2 Jul 2015 16:01:28 +0200 Subject: [PATCH 40/42] passing stream events through to schema object. --- lib/schema.js | 11 +++++---- test/schema.test.js | 54 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/lib/schema.js b/lib/schema.js index 5d0ebb2..c1bd15c 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -17,10 +17,13 @@ var Schema = DocumentType.extend({ } }, stream: function() { - var schema = this; - return es.map(function(doc, done) { - schema.parse(doc); - done(); + var that = this; + var stream = es.map(function(doc, done) { + that.parse(doc); + that.trigger('data', doc, that); + done(null, doc); + }).on('end', function () { + that.trigger('end', that); }); return stream; }, diff --git a/test/schema.test.js b/test/schema.test.js index de96952..7e6f5a0 100644 --- a/test/schema.test.js +++ b/test/schema.test.js @@ -54,6 +54,22 @@ describe('Schema', function () { done(); }); }); + + it('should trigger `data` events for each doc', function (done) { + var docs = [{foo: 1}, {bar: 1, foo: 2}]; + var src = es.readArray(docs); + var count = 0; + src.pipe(schema.stream()) + .on('data', function (doc) { + debug('doc', doc); + count ++; + }) + .on('end', function () { + assert.equal(count, 2); + done(); + }); + }); + }); describe('Schema Helper', function() { @@ -90,19 +106,35 @@ describe('Schema Helper', function() { }); }); - it('should trigger data events for each doc', function (done) { + it('schema object should also trigger `end` event when done parsing', function (done) { + var docs = [{foo: 1}, {bar: 1, foo: 2}]; + var src = es.readArray(docs); + var schema; + schema = schemaHelper('with.stream', src, function () { + assert.ok(schema.fields.get('foo')); + assert.ok(schema.fields.get('bar')); + }).on('end', function(schema) { + assert.equal(schema.count, 2); + done(); + }); + }); + + it('schema object should also trigger `data` events for each doc', function (done) { var docs = [{foo: 1}, {bar: 1, foo: 2}]; var src = es.readArray(docs); var count = 0; - var schema = new Schema(); - src - .on('data', function (doc) { - debug('doc', doc); - count ++; - }) - .on('end', function () { - assert.equal(count, 2); - done(); - }); + var schema; + schema = schemaHelper('with.stream', src, function () { + assert.ok(schema.fields.get('foo')); + assert.ok(schema.fields.get('bar')); + }).on('data', function(doc, innerSchema) { + count ++; + assert.ok(doc); + assert.equal(schema, innerSchema); + }).on('end', function () { + assert.equal(count, 2); + done(); + }); }); + }); From 469e7aafbaaa0a720da98d3bb46fcccd39f47c11 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Thu, 2 Jul 2015 22:21:53 +0200 Subject: [PATCH 41/42] fixed bug that under counted total_count --- lib/field-collection.js | 4 +++- test/mixed-type-probability.test.js | 8 +++++++- test/schema.test.js | 1 - 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/field-collection.js b/lib/field-collection.js index 86399e4..2c6ea4e 100644 --- a/lib/field-collection.js +++ b/lib/field-collection.js @@ -39,11 +39,13 @@ var FieldCollection = Collection.extend(lodashMixin, parentMixin, { /** * first time we see this field. We need to compensate for * the Undefined values we missed so far for this field, - * by setting the count to the parent count. + * by setting the count to the parent count and adjusting + * total_count as well. */ if (this.parent && this.parent.count > 0) { var undef = field.types.add({name: 'Undefined'}); undef.count += this.parent.count; + field.total_count += undef.count; } } // undefined are not counted towards the field's count diff --git a/test/mixed-type-probability.test.js b/test/mixed-type-probability.test.js index 6a5d0a4..e564d5b 100644 --- a/test/mixed-type-probability.test.js +++ b/test/mixed-type-probability.test.js @@ -1,5 +1,6 @@ var getSchema = require('../'); var assert = require('assert'); +var debug = require('debug')('mongodb-schema:test'); describe('mixed type probability', function() { var docs = [ @@ -16,7 +17,8 @@ describe('mixed type probability', function() { registered: true }, { - _id: 4 + _id: 4, + assigned: true } ]; @@ -48,4 +50,8 @@ describe('mixed type probability', function() { it('should have a probability of 25% for `registered` to be undefined', function() { assert.equal(schema.fields.get('registered').types.get('Undefined').probability, (1 / 4)); }); + it('should compensate for missed Undefined values', function() { + assert.equal(schema.fields.get('assigned').probability, 0.25); + assert.equal(schema.fields.get('assigned').types.get('Boolean').probability, 0.25); + }); }); diff --git a/test/schema.test.js b/test/schema.test.js index 7e6f5a0..69c8668 100644 --- a/test/schema.test.js +++ b/test/schema.test.js @@ -61,7 +61,6 @@ describe('Schema', function () { var count = 0; src.pipe(schema.stream()) .on('data', function (doc) { - debug('doc', doc); count ++; }) .on('end', function () { From 2b8766b685326f20420979f13c0d65804859d0d7 Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Fri, 3 Jul 2015 08:49:12 +0200 Subject: [PATCH 42/42] fixed bug where undefined values did not count towards total_count --- lib/field-collection.js | 4 +++- test/mixed-type-probability.test.js | 8 +++++++- test/schema.test.js | 1 - 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/field-collection.js b/lib/field-collection.js index 86399e4..2c6ea4e 100644 --- a/lib/field-collection.js +++ b/lib/field-collection.js @@ -39,11 +39,13 @@ var FieldCollection = Collection.extend(lodashMixin, parentMixin, { /** * first time we see this field. We need to compensate for * the Undefined values we missed so far for this field, - * by setting the count to the parent count. + * by setting the count to the parent count and adjusting + * total_count as well. */ if (this.parent && this.parent.count > 0) { var undef = field.types.add({name: 'Undefined'}); undef.count += this.parent.count; + field.total_count += undef.count; } } // undefined are not counted towards the field's count diff --git a/test/mixed-type-probability.test.js b/test/mixed-type-probability.test.js index 6a5d0a4..e564d5b 100644 --- a/test/mixed-type-probability.test.js +++ b/test/mixed-type-probability.test.js @@ -1,5 +1,6 @@ var getSchema = require('../'); var assert = require('assert'); +var debug = require('debug')('mongodb-schema:test'); describe('mixed type probability', function() { var docs = [ @@ -16,7 +17,8 @@ describe('mixed type probability', function() { registered: true }, { - _id: 4 + _id: 4, + assigned: true } ]; @@ -48,4 +50,8 @@ describe('mixed type probability', function() { it('should have a probability of 25% for `registered` to be undefined', function() { assert.equal(schema.fields.get('registered').types.get('Undefined').probability, (1 / 4)); }); + it('should compensate for missed Undefined values', function() { + assert.equal(schema.fields.get('assigned').probability, 0.25); + assert.equal(schema.fields.get('assigned').types.get('Boolean').probability, 0.25); + }); }); diff --git a/test/schema.test.js b/test/schema.test.js index 7e6f5a0..69c8668 100644 --- a/test/schema.test.js +++ b/test/schema.test.js @@ -61,7 +61,6 @@ describe('Schema', function () { var count = 0; src.pipe(schema.stream()) .on('data', function (doc) { - debug('doc', doc); count ++; }) .on('end', function () {