Introduction
The primary purpose behind a dataModel is the management of RESTful data and related logic.
Just like a viewModel or router, a dataModel can be bound against your UI/markup (either on its own or integrated into a <component>). An example usage of this might be binding a dataModel against a HTML <form> to enable CRUD-type operations on a database.
A dataModel is really just an enhanced viewModel, meaning you can use it in exactly the same way you would a viewModel, but with the added ability of being able to have its data loaded from/saved to a RESTful endpoint as well as a host of other related features.
Usage
A dataModel can be instantiated and used in 3 different ways:
-
Manually initialized (standard KnockoutJS methodology), and optionally bound to the DOM (See: manual binding).
markup.html<form id="person" data-bind="submit: save"> Name: <input type="text" data-bind="value: name"> <button>Save</button> </form>
markup.jsvar DataModel = fw.dataModel.create({ url: '/person', initialize: function() { this.name = fw.observable(); } }); fw.applyBindings(new DataModel(), document.getElementById('person'));
-
Automatically via a <dataModel module="moduleName"> ... </dataModel> declaration in the DOM (See: <dataModel> usage).
markup.html<dataModel module="Person"> <form id="person" data-bind="submit: save"> Name: <input type="text" data-bind="value: name"> <button>Save</button> </form> </dataModel>
markup.jsfw.dataModel.create({ namespace: 'Person', autoRegister: true, initialize: function() { this.name = fw.observable(); } }); fw.start();
- Automatically via a <component-name></component-name> declaration in the DOM (See: <component> usage).
NOTE: There are many ways to register and/or load a dataModel so it can be found/used when needed. See: dataModel registration.
Factory Method
Each different type of dataModel you wish to have must have a new constructor function created for it. These constructor functions are then used (either by you directly or by Footwork) to instantiate new dataModel instances per your definition (which are then used and/or bound to your UI).
dataModel constructor functions are created by calling the factory method fw.dataModel.create() and passing it a configuration object.
The resulting constructor function can then be used to instantiate new instances of that dataModel. These constructor functions are essentially specialized wrappers which enable Footwork to hook into your dataModel/module to provide for all of the features a dataModel provides.
var DataModelConstructor = fw.dataModel.create({
/**
* The namespace (communications channel) the dataModel uses. This is essentially used as
* the 'key' for CQRS separation between modules. If no namespace is provided a unique one
* will be automatically assigned.
*/
namespace: 'Person', // example namespace name, any alpha-numeric is valid
/**
* URL to use for RESTful operations.
* You should provide either a string value or an evaluator function which will be used to
* determine the URL endpoint each time a request is made.
*/
url: '/path/to/endpoint',
url: function() { return '/path/to/endpoint'; },
// Note that the url option can have mapped variables interpolated into the string
url: '/path/:mappedVariable/to/endpoint/',
url: function() { return '/path/:mappedVariable/to/endpoint'; },
/**
* Attribute to use as the primary key (id) of the model.
* This idAttribute will be automatically created/instantiated on your dataModel as an
* observable, its value will also be used for AJAX requests.
*/
idAttribute: 'id', // default === 'id'
/**
* Flag telling Footwork whether or not to include the primary key in the URL when
* performing REST operations.
* IE: Use of '/path/to/endpoint/1' vs '/path/to/endpoint'
*/
useKeyInUrl: true, // default === true
/**
* Parse function called whenever a models data is returned by the server from either a
* save() or fetch().
* This method is passed the response object and should return the attributes hash to be
* set() on the dataModel. By default this method simply returns the responseObject back
* to be used in the set() call.
*/
parse: function(responseObject) { return { /* ... */ }; },
/**
* Options passed to fw.sync() for every request.
* Valid values are the same as jQuery.ajax(), http://api.jquery.com/jquery.ajax/
*/
ajaxOptions: {},
ajaxOptions: function() { return optionsObject; },
/**
* A configurable lull-time for the isSaving/isFetching/isDestroying observables on the dataModel
* This is so that (for example) when a user .save()'s a dataModel it will not flip-flop the
* isSaving observable too quickly. This value defaults to 0 (no delay/lull time).
*/
requestLull: 200, // make requests lull for atleast 200msec
requestLull: function(requestType) {
return 200; // lull-time returned via callback
},
/**
* If true, Footwork will register the dataModel under its namespace name. This means
* that when this fw.dataModel.create() call is made it will automatically call
* fw.dataModel.register('Person', ThisdataModelConstructor)
* This is a (handy) way of telling Footwork how to find your dataModel when it needs it.
*/
autoRegister: false, // default === false
/**
* If true, the namespace will have an auto-incremented 0-based index number appended for
* each new dataModel (ie: new instances will not share the same namespace).
*/
autoIncrement: false, // default === false
/**
* Initialization function called at creation of a new dataModel.
* Note: it is passed in the parameters supplied at creation.
*/
initialize: function(param1, param2, ...) {
// this === the dataModel instance
var dataModel = this;
// Perform normal dataModel initialization here, just like typical knockout.js code.
dataModel.param1 = fw.observable(param1);
},
// Called after initialize() and after binding to the DOM
afterRender: function(containingElement) {
// this === the dataModel instance
},
/**
* Called after afterRender() and after all nested components/viewModels/etc have been resolved.
*
* This enables you to control when the module is 'resolved', such as when you need to
* load some data before displaying to the user. Parent components/etc will not resolve until
* their children do. If you are using animations they will not trigger on a component until it
* is resolved.
*/
afterResolving: function(resolve) {
// If this method is defined you will have to call the passed in resolve() callback once
// your dataModel is 'resolved'.
// You can pass it a truthy value to indicate resolution is complete:
resolve(true);
// You can pass it a promise, footwork will wait for it to be resolved or fail:
resolve(promiseToWaitFor);
// You can pass it an array of promises for footwork to wait to be resolved or fail:
resolve([ promiseToWaitFor, anotherPromiseToWaitFor ]);
// Note that if you call resolve(false) nothing will occur, footwork will not tell
// higher-level viewModel/dataModel/etc that your module is resolved until you call
// resolve(true) or hand it a promise that resolves/fails.
},
// Function called just before the html this dataModel is bound to is removed from the DOM
onDispose: function(containingElement) {
// this === the dataModel instance
},
// When used in a component, ensure that (if being animated) they are sequenced in with a
// minimum time between animations.
sequenceAnimations: 100, // 100ms minimum
sequenceAnimations: function() { return 100; }, // 100ms minimum
/**
* Attributes/properties that are extended onto each newly instantiated dataModel
* NOTE: Only suitable for primitive values (strings, numbers, etc) or functions, do not
* put observables or namespaces/etc here as they are shared across instances.
*/
extend: {
prop1: 'value',
prop2: 123
},
// Behavioral mixins to include with each new dataModel created
mixins: [
// See: 'Mixins' section on this page
]
});
NOTE: All configuration parameters are optional.
Manual Instantiation and Binding
Manually instantiating a dataModel is done by calling new ConstructorFunc(). With the instance in hand you can then use it as you wish, either directly or by binding it to the DOM (just as you might a viewModel).
To manually bind a dataModel you use a fw.applyBindings() call after instantiating it.
var Person = fw.dataModel.create({
namespace: 'Person',
initialize: function(params) {
// params === object passed in when calling new Person( ... )
this.firstName = fw.observable(person.firstName).mapTo('firstName');
this.lastName = fw.observable(person.lastName).mapTo('lastName');
this.isBestFriend = fw.observable(params.isBestFriend).mapTo('isBestFriend');
}
});
var bestFriend = new Person({ firstName: 'Patrick', lastName: 'Bateman', isBestFriend: true });
Now, if we wish, we can bind the Person instance (bestFriend) to the DOM:
fw.applyBindings(bestFriend, document.getElementById('best-friend'));
<dataModel>
A dataModel can be instantiated and bound automatically when using a <dataModel> declarative wrapper element. Using the module="" attribute you can specify which dataModel should be instantiated and bound by Footwork.
<dataModel module="Person">
<form>
First Name: <input type="text" data-bind="value: firstName">
Last Name: <input type="text" data-bind="value: lastName">
<input type="submit" value="Save">
</form>
</dataModel>
... and as an example, this dataModel was registered directly:
fw.dataModel.register('Person', fw.dataModel.create({
namespace: 'Person',
initialize: function(params) {
this.firstName = fw.observable(person.firstName).mapTo('firstName');
}
})
);
NOTE: You can have your dataModel automatically downloaded for you when needed.
See dataModel registration for information on how to tell Footwork where to find your dataModel module.
<component>
In addition to using a dataModel in the ways shown above they can also be used inside of a custom <component>.
For more information on how to create a dataModel-based component see the component documentation.
Data Management
A dataModel is a construct provided by Footwork which enables easy management of data which maps to a RESTful endpoint.
This includes functionality for:
- Telling the framework where the data is and how it maps to the other side.
- How to read the data from your dataModel.
- How to set that data in your dataModel.
- How to fetch the data from its REST endpoint.
- How to save the data to its REST endpoint.
- How to delete/destroy the data on its REST endpoint.
Mapping / Getting / Setting Data
In order to perform REST operations you will need to be able to map, get, and set the data on your dataModel.
The following sections describe how to perform those operations.
Mapping Data
When sending to or retreiving from from the server Footwork needs to know how to transpose that data to and from your dataModel. Using observable.mapTo() we can define how our data maps to the representation the server expects.
NOTE: observable.mapTo() is generally expected to be called from within a dataModel initialize function.
If you call .mapTo() sometime after or outside of the main dataModel initialize method then you will need to provide it a direct reference to the dataModel instance using the { path: '', dataModel: instance } object-notation version.
var Person = fw.dataModel.create({
namespace: 'Person',
initialize: function(params) {
this.firstName = fw.observable(params.firstName).mapTo('firstName');
this.lastName = fw.observable(params.lastName).mapTo('lastName');
this.age = fw.observable(params.attributes.age).mapTo('attributes.age');
this.inTheMachine = fw.observable(params.attributes.inTheMachine).mapTo('attributes.inTheMachine');
}
});
var person = new Person();
person.set({
firstName: 'Kevin',
lastName: 'Flynn',
attributes: {
age: 33,
inTheMachine: true
}
});
/**
* person.inTheMachine() === true
* person.get() === {
* id: 1,
* firstName: 'Kevin',
* lastName: 'Flynn',
* attributes: {
* age: 33,
* inTheMachine: true
* }
* }
*/
Getting / Reading
Sometimes you need to convert a dataModel to JSON or want to grab its values.
To do this you can either reference the mapped observables directly (which requires a lot of boilerplate) or use one of the supplied dataModel methods which gathers the data together/based on the mappings you have setup.
var Person = fw.dataModel.create({
namespace: 'Person',
initialize: function(params) {
this.firstName = fw.observable(params.firstName).mapTo('firstName');
this.lastName = fw.observable(params.lastName).mapTo('lastName');
}
});
var person = new Person({
firstName: 'Gary',
lastName: 'Busey'
});
/**
* person.get() === {
* id: 1,
* firstName: 'Gary',
* lastName: 'Busey'
* }
*
* person.get('firstName') === 'Gary'
*/
var Person = fw.dataModel.create({
namespace: 'Person',
initialize: function(params) {
this.firstName = fw.observable(params.firstName).mapTo('firstName');
this.lastName = fw.observable(params.lastName).mapTo('lastName');
}
});
var person = new Person({
firstName: 'Gary',
lastName: 'Busey'
});
// person.toJSON() === '{"firstName":"Gary","lastName":"Busey"}'
// JSON.stringify(person) === '{"firstName":"Gary","lastName":"Busey"}'
Setting / Writing
When you are not using one of the RESTful methods (like dataModel.fetch()) to retrieve and set the values in your dataModel you will need to set them by some other means.
One method is to write to the underlying observables that are mapped inside of your dataModel. You might do this when a click event or some other internal event occurs that originates from inside your application.
var Person = fw.dataModel.create({
namespace: 'Person',
initialize: function(params) {
this.firstName = fw.observable().mapTo('firstName');
this.lastName = fw.observable().mapTo('lastName');
this.isDead = fw.observable(false).mapTo('isDead');
this.kill = function() {
this.isDead(true);
};
}
});
var person = new Person();
// This method writes a value directly to the underlying observable
person.kill();
Another possibility is that you have the dataModel bound to the DOM and it is manipulated via the user and two-way bindings (ex: when a dataModel is bound to an HTML <form>).
This works in many circumstances, and might in fact be what you want/need to do.
However if you are handling data from the server/REST endpoint for your dataModel then you likely want to write that data using the mappings you have setup. Otherwise you will have to manually map and write that data to each underlying observable, which may or may not be a direct 1-to-1 mapping and requires a lot more boilerplate.
Footwork provides a dataModel.set() method which will take the (plain object) data you pass it, map it to the variables in your dataModel and write to them as appropriate.
var Person = fw.dataModel.create({
namespace: 'Person',
initialize: function(params) {
this.firstName = fw.observable(params.firstName).mapTo('firstName');
this.lastName = fw.observable(params.lastName).mapTo('lastName');
this.isDead = fw.observable(false).mapTo('attr.dead');
}
});
var person = new Person();
// person.isDead() === false
person.set({
firstName: 'Gary',
lastName: 'Busey',
attr: {
dead: true
}
});
// person.firstName() === 'Gary'
// person.isDead() === true
// ...and you can also just pass a single value to set
person.set('firstName', 'Jake');
// person.firstName() === 'Jake'
REST / AJAX Operations
A dataModel is often times used to communicate or transfer state to/from a RESTful endpoint.
To aid in performing those operations, Footwork provides a number of useful methods/features.
The method Footwork calls to read (dataModel.fetch()), delete (dataModel.destroy()), or create/patch/update (dataModel.save()) the dataModel on the server (you typically do not call this directly).
// Create a new type of collection with the requisite dataModel (that has a REST url)
var Person = fw.dataModel.create({
url: '/person',
initialize: function() { /* ... */ }
});
var person = new Person();
person.sync('read', person).then(function(personData) {
console.info('Person returned', personData);
});
Fetching Model Data
To fetch the data for a dataModel it must be configured with a url, see the fw.dataModel.create() factory method for details on that option.
Assuming that has been done, fetching the data is done via a call to dataModel.fetch().
var Person = fw.dataModel.create({
namespace: 'Person',
url: '/person',
initialize: function(params) {
this.id = fw.observable(params.id).mapTo('id');
this.firstName = fw.observable(params.firstName).mapTo('firstName');
this.lastName = fw.observable(params.lastName).mapTo('lastName');
this.isDead = fw.observable(false).mapTo('attr.dead');
}
});
var person = new Person({
id: 1
});
// person.isDead() === false
// ... some time later
person.fetch().then(function() {
// person.firstName() === 'Gary'
// person.isDead() === true
});
Saving Model Data
To save the data for a dataModel it must be configured with a url, see the fw.dataModel.create() factory method for details on that option.
Assuming that has been done, saving the data is done via a call to dataModel.save(). You can save either the entire dataModel (all the mapped values), or save specific data by passing it the appropriate parameters.
var Person = fw.dataModel.create({
namespace: 'Person',
url: '/person',
initialize: function(params) {
this.id = fw.observable(params.id).mapTo('id');
this.firstName = fw.observable(params.firstName).mapTo('firstName');
this.lastName = fw.observable(params.lastName).mapTo('lastName');
this.isDead = fw.observable(false).mapTo('attr.dead');
}
});
var person = new Person({
id: 1,
firstName: 'Alfred',
lastName: 'Hitchcock'
});
person.save().then(function() {
console.info('dataModel saved successfully.');
});
Deleting / Destroying Model Data
To delete or destroy the data for a dataModel (send the DELETE request) to its endpoint it must be configured with a url, see the fw.dataModel.create() factory method for details on that option.
Assuming that has been done, destroying the data is done via a call to dataModel.destroy().
var Person = fw.dataModel.create({
namespace: 'Person',
url: '/person',
initialize: function(params) {
this.id = fw.observable(params.id).mapTo('id');
this.firstName = fw.observable(params.firstName).mapTo('firstName');
this.lastName = fw.observable(params.lastName).mapTo('lastName');
this.isDead = fw.observable(false).mapTo('attr.dead');
}
});
var person = new Person({
id: 1
});
person.destroy().then(function() {
console.info('dataModel destroyed successfully.');
});
Lifecycle & Registration
Each dataModel instantiated and bound to the DOM will receive lifecycle events.
These events can be used for any logic you need to incorporate when the instance is initially setup/bound onto or removed from the page. A common example would be the setup and teardown of a jQuery plugin, or events.
Registration of a dataModel is referring to telling Footwork (in one way or another) where your dataModel is so that it can be used when needed.
Lifecycle
A dataModel is instantiated, then bound to the DOM and used, or just used independent of the DOM. Depending on what you choose to do with a dataModel determines its exact lifecycle.
Lifecycle events are automatically triggered for you when using a dataModel via one of the three main methods:
- Use the <dataModel> ... </dataModel> declarative syntax.
- Use the <component-name></component-name> declarative syntax.
- Manually bound (fw.applyBindings()) to the DOM.
A dataModel that is attached to the DOM will retrive two main lifecycle events, one just after binding to the DOM (afterRender()) and one when the element (that the dataModel bound itself to) is removed from the DOM (onDispose(), called just before the element is removed).
Binding
If provided, the dataModel configuration afterRender() method will be called just after a dataModel is bound to the DOM. This provides a handy integration point for external libraries or plugins (such as jQuery).
var Person = fw.dataModel.create({
namespace: 'Person',
afterRender: function(domElement) {
var person = this;
domElement.addEventListener('click', function() {
console.info('You clicked', person.firstName());
});
},
initialize: function(params) {
this.firstName = fw.observable().mapTo('firstName');
}
});
Disposal
If provided, the dataModel configuration onDispose() method will be called just after the element a dataModel is bound to is removed from the DOM. This provides a handy integration point for external libraries or plugins (such as jQuery).
var Person = fw.dataModel.create({
namespace: 'Person',
afterRender: function(domElement) {
domElement.addEventListener('click', this.clickPerson);
},
onDispose: function(domElement) {
domElement.removeEventListener('click', this.clickPerson);
},
initialize: function(params) {
var person = this;
this.firstName = fw.observable(params.firstName).mapTo('firstName');
this.clickPerson = function() {
console.info('You clicked', person.firstName());
};
}
});
If you do not bind a dataModel to the DOM then you will want to clean up its references and subscriptions when you are done with it. This is done by calling dataModel.dispose() directly.
var MydataModel = fw.dataModel.create({ /* ... */ });
var dataModel = new MydataModel();
// ...
dataModel.dispose(); // all namespaces, handlers, and subscriptions now cleaned up/removed
var someOtherObservable = fw.observable();
var MyDataModel = fw.dataModel.create({
initialize: function() {
// Make dataModel the instance reference
var dataModel = this;
dataModel.myVarSub = someOtherObservable.subscribe(function() {
// This subscription will get cleaned up when the dataModel is disposed
});
dataModel.$namespace.command.handler('doSomething', function() {
// This command handler will get cleaned up when the dataModel is disposed
});
dataModel.$someOtherNamespace = fw.namespace('SomeOtherNamespace');
dataModel.$someOtherNamespace.command.handler('doSomethingElse', function() {
// This command handler will get cleaned up when the dataModel is disposed
});
}
});
Registration
In order for Footwork to know what to do when it encounters a <dataModel> declaration it must be registered in some way (it needs to know where it is).
Footwork supports both explicitly registering your dataModel ahead of time (caching its constructor function or instance directly) or by telling it where it can be downloaded (automatically/lazy loading via AMD/RequireJS).
You can register your module with one of the following methods:
- fw.dataModel.register() - Register (cache) a dataModel explicitly.
- fw.dataModel.registerLocation() - Register the location of a dataModel so that it can be dynamically loaded at some time in the future.
In either case, the declarative <dataModel module="moduleName"> ... </dataModel> syntax will trigger the loading (if necessary), instantiation, and binding of the dataModel.
NOTE: AMD/RequireJS is fully supported (and highly encouraged) for a number of reasons:
- It strongly encourages modularization and separation of concerns.
- Helps decouple your application and allow for easier testability.
- Footwork can take advantage of its dependency resolution to automatically load and use resources for you as needed at runtime (including the automatic loading and composing of entire (including nested) views/pages, routers, components, viewModels, or dataModels).
- Allows for easier debugging as non-compiled assets while still being buildable for release into a production environment.
- Allows for easy and highly configurable caching/preloading of assets (this includes all components, dataModels, and templates). None, some, or all of it...you choose what your users wait for.
Module Resolution
There are 3 ways Footwork will try to resolve your dataModel when it encounters the declarative <dataModel module="moduleName"> ... </dataModel> element you place in the DOM.
Here they are in order of priority:
- Explicitly registered with a fw.dataModel.register() call.
- Automatic download/resolution via AMD/RequireJS at a pre-registered location (fw.dataModel.registerLocation()).
- Automatic download/resolution via AMD/RequireJS at the configurable default (fw.dataModel.defaultLocation()).
Registering a dataModel explicitly with fw.dataModel.register() makes it immediately available. Any <dataModel module="moduleName"> ... </dataModel> declarations encountered will be processed with no delay (the dataModel is 'cached' when registered).
The 2 methods registerLocation() and defaultLocation() tell Footwork where it can download your dataModel module (in the event you do not explicitly register it). In any case your markup will wait until the dataModel is resolved prior to being initialized.
// register a Footwork dataModel
fw.dataModel.register('Person', fw.dataModel.create({
this.isCool = fw.observable(false);
}));
// register a normal class constructor function (like in regular knockout)
fw.dataModel.register('Person', function() {
this.isCool = fw.observable(false);
});
// register an instance of an object (like in regular knockout)
fw.dataModel.register('Person', {
instance: { isCool: false }
});
/**
* A constructor function to be called when the declaration is encountered.
* It is supplied params given at the binding (<dataModel params="exampleParam: true">) and
* the containing element of the dataModel.
*/
fw.dataModel.register('Person', {
createDataModel: function(params, info) {
// info.element = containing <dataModel> element
// params are the parameters declaratively created from the DOM
return { isCool: false }; // object representing the dataModel to be bound against the DOM
}
});
NOTE: Are you using a fw.dataModel.create() constructor and simply want to register it using the namespace name (recommended)?
You can optionally just set autoRegister: true in the dataModel configuration object, then the fw.dataModel.register call is taken care of for you when the router constructor is created.
See: dataModel configuration.
// Load Person from: /dataModels/Person.js (based on dataModel/module name, case sensitive)
fw.dataModel.registerLocation('Person', '/dataModels/');
// Load Person from: /dataModels/DifferentFileName.js (specify full file name)
fw.dataModel.registerLocation('Person', '/dataModels/DifferentFileName.js');
// Load all *-store from /stores/
fw.dataModel.registerLocation(/.*-store/, '/stores/');
// register the location of several dataModels at once (ie: all in the same folder)
fw.dataModel.registerLocation(['Reservations', 'Invoices', 'Notes'], '/dataModels/stuff/');
// Load all dataModels from /mydataModels/[module-name].js (case sensitive)
fw.dataModel.defaultLocation('/myDataModels/');
Module Formats
Loading your dataModel in so that Footwork can use it is done via a script loader.
Both AMD/RequireJS and Browserify are supported. However RequireJS is preferred as it will enable Footwork to resolve your dataModels/etc (and their dependencies) automatically at runtime as needed.
The following example shows the RequireJS/AMD flavored version:
define(["footwork"],
function(fw) {
// return the constructor created by fw.dataModel.create()
return fw.dataModel.create({
namespace: 'Person'
initialize: function() {
// ...
}
});
}
);
Mixins
Mixins are about reusing behavior, functionality, and code whenever possible. They allow you to write various behaviors/logic and then later on combine and compose them as you want at runtime.
The mixin functionality in Footwork is provided via a library called riveter. All fw.dataModel.create() based constructor functions are riveter constructor functions. Above and beyond the functionality outlined here, each object has various methods extended from riveter which can enable you to extend dataModels in various ways, it is recommended you to also look at its documentation.
Basic usage:
var bigSprocket = { /* mixin configuration object */ };
var bikeSprocket = { /* mixin configuration object, detailed in the next section */ };
/**
* Mixin behavior is applied to a dataModel by passing it into the
* fw.dataModel.create() configuration object
* NOTE: mixins are applied to the dataModel in the order they are given.
*/
var Sprocket = fw.dataModel.create({
// ... dataModel configuration object
namespace: 'Sprocket',
initialize: function(param) {
this.type = param.type;
},
// mixins/behavior to include for each new 'Sprocket' dataModel
mixins: [ bigSprocket, bikeSprocket ]
});
var mySprocket = new Sprocket({ type: 'awesome' });
Configuration
Each mixin is simply a configuration object defining certain behaviors, functionality, and logic. The behavior you define will be added to each dataModel instance it is configured with.
Mixin configuration object synopsis:
// define 'bigSprocket' as an object to serve as the configuration container
var bigSprocket = {
_preInit: function(param1, param2, ...) {
/**
* called prior to the initialize() method from the dataModel configuration being called
* params === params passed in at creation
* this === the dataModel
*/
},
mixin: {
/**
* these properties are added the instance object immediately upon creation, before
* any methods (including _preInit) are called
*/
function1: function() {
// function that is extended onto the dataModel object (this) upon creation
},
function2: function() {
// another function that is extended onto the dataModel object (this) upon creation
},
property1: 'someValue' // a raw property extended to the object
// ...
},
_postInit: function() {
/**
* called after the initialize() method from the dataModel configuration is called
* this === the dataModel instance
*/
}
};
- If you require some other type of object extension or mixin, as recommended above you should look at the riveter documentation.
- A dataModel can have as many mixins as you want, and you can re-use them across as many differing dataModels/modules as you like.
Usage
Each mixin behavior is added to each new instance of the dataModel that is created. This goes for ones instantiated automatically via declarative HTML, or directly/manually in javascript code.
All mixins may be reused on both a standalone dataModel and dataModels attributed with a component.
Example usage:
// define the mixin configuration object
var bigSprocket = {
_preInit: function(param) {
this.isAwesome = (param.type === 'awesome' ? true : false);
// this.isBig === true
},
mixin: {
isBig: true,
fitInSmallPlace: function() {
return false;
}
}
};
// create a BigSprocket contructor and include the bigSprocket mixin
var BigSprocket = fw.dataModel.create({
namespace: 'Sprocket',
initialize: function(param) {
this.type = param.type;
},
mixins: [ bigSprocket ]
});
var mySprocket = new BigSprocket({ type: 'awesome' });
// mySprocket.fitInSmallPlace() === false
// mySprocket.isBig === true
// mySprocket.isAwesome === true
Utility Functions
Various useful methods and utility functions for miscellaneous and debugging purposes.
var Bike = fw.dataModel.create({
namespace: 'Bike',
initialize: function() {
this.isBike = true;
}
});
var Wheel = fw.dataModel.create({
namespace: 'Wheel',
initialize: function() {
this.isWheel = true;
}
});
var bike = new Bike();
var wheel1 = new Wheel();
var wheel2 = new Wheel();
var dataModels = fw.dataModel.getAll();
// dataModels['Bike'][0].isBike === true
// dataModels['Wheel'].length === 2
// dataModels['Wheel'][0].isWheel === true
// Note: specifying a single namespace will result in the only those instances being returned
var dataModels = fw.dataModel.getAll('Wheel'); // get all 'Bike' instances
// dataModels[0].isWheel === true
// dataModels[1].isWheel === true
var dataModels = fw.dataModel.getAll(['Bike', 'Wheel']); // get all 'Bike' and 'Wheel' instances
// dataModels === {
// Bike: [ { ... } ],
// Wheel: [ { ... }, { ... } ]
// }
fw.dataModel.register('Bike', fw.dataModel.create({
namespace: 'Bike',
initialize: function() {
this.isBike = true;
}
}));
// fw.dataModel.isRegistered('Bike') === true
// fw.dataModel.isRegistered('ModuleThatIsLoadedByAMD') === false
// Explicit registration
var Bike = fw.dataModel.create({ /* ... configuration object */ });
fw.dataModel.register('Bike', Bike);
// fw.dataModel.getRegistered('Bike') === Bike;
// dataModel that registers itself
var Person = fw.dataModel.create({
namespace: 'Person',
autoRegister: true,
// ...
});
// fw.dataModel.getRegistered('Person') === Person;
fw.dataModel.registerLocation('Person', '/path/to/dataModel/folder');
// fw.dataModel.getLocation('Person') === '/path/to/dataModel/folder'
var fileNameForPerson = fw.dataModel.getFileName('Person'); // === Person.js
/**
* If the dataModel was explicitly registered (cached), then null is returned for any
* fileType because the file name will never be used.
*/
fw.dataModel.register('Person', fw.dataModel.create({ /* configuration object */ }) );
var fileNameForPerson = fw.dataModel.getFileName('Person'); // === null
// explicitly set the extension
fw.dataModel.fileExtensions('.jscript'); // append dataModel module files with '.jscript'
// You can also specify a function() whose return value is used as the extension.
fw.dataModel.fileExtensions(function(moduleName) {
if(moduleName === 'Sprocket') {
return '.jscript';
} else {
return '.js';
}
});
Instance Properties
After a dataModel has been created, there are a few properties which are on the instantiated object.
var Navigation = fw.dataModel.create({
namespace: 'Navigation',
initialize: function() {
this.$namespace.event.handler('userLoggedIn', function(username) {
console.log('Welcome', username);
});
}
});
The root (non-indexed) namespace channel created as a result of the namespace: configuration attribute given.
A dataModel namespace is automatically indexed by default (unless you specify autoIncrement: false to its configuration).
If you do not provide that configuration option then each new dataModel instance will have an indexed namespace name, the $rootNamespace is the namespace channel provided which hooks into the non-indexed (root) namespace name.
fw.dataModel.create({
namespace: 'Person',
initialize: function() {
this.$rootNamespace.event.handler('wasFound', function() {
console.log('Person, not Person0 or Person1, received this event.');
});
}
});
Global namespace channel all instances get access to. Think of this as a broadcast channel everyone can talk on.
fw.dataModel.create({
namespace: 'Person',
initialize: function() {
var thisPerson = this;
this.$globalNamespace.command.handler('sayHello', function() {
console.log('Hello from', thisPerson);
});
}
});
var Navigation = fw.dataModel.create({
namespace: 'Navigation',
initialize: function() {
// this.$cid === 'ed53b42d-faa0-a251-29c1-e396d9f083bc'
}
});
var Navigation = fw.dataModel.create({
namespace: 'Navigation',
idAttribute: 'myId',
initialize: function() {
// idAttribute automatically instantiated and .mapTo()'d for you, here we assign it a value of 10
this.myId(10);
// this.myId() === 10
// this.$id() === 10
// this.myId === this.$id
}
});
var Person = fw.dataModel.create({ /* ... */ });
var person = new Person();
// person.isNew() === true
person.id(1);
// person.isNew() === false
NOTE: This observable has a configurable requestLull (see the: factory configuration) which will cause this observable to 'lull' in the true state for a minimum period of time. This allows you to bind to a reliable indicator which will tell the user the state of the dataModel without thrashing the UI.
<dataModel module="Person">
<form data-bind="submit: save">
Name: <input type="text" data-bind="value: name">

<button>Save Now</button>

Saving data, please wait...

</form>
</dataModel>
NOTE: This observable has a configurable requestLull (see the: factory configuration) which will cause this observable to 'lull' in the true state for a minimum period of time. This allows you to bind to a reliable indicator which will tell the user the state of the dataModel without thrashing the UI.
<dataModel module="Person">
<form data-bind="submit: save">

Fetching data, please wait...

Name: <input type="text" data-bind="value: name">

</form>
</dataModel>
NOTE: This observable has a configurable requestLull (see the: factory configuration) which will cause this observable to 'lull' in the true state for a minimum period of time. This allows you to bind to a reliable indicator which will tell the user the state of the dataModel without thrashing the UI.
<dataModel module="Person">
<form data-bind="submit: save">

Removing person, please wait...

<button data-bind="click: destroy">Delete Person</button>

</form>
</dataModel>
NOTE: This observable has a configurable requestLull (see the: factory configuration) which will cause this observable to 'lull' in the true state for a minimum period of time. This allows you to bind to a reliable indicator which will tell the user the state of the dataModel without thrashing the UI.
<dataModel module="Person">
<form data-bind="submit: save">

Doing something to the person, please wait...

<button data-bind="click: destroy">Delete Person</button>
<button data-bind="click: save">Save Person</button>

</form>
</dataModel>
var Person = fw.dataModel.create({
namespace: 'Person',
initialize: function() {
this.isPerson = fw.observable();
this.disposeWithInstance(this.isPerson.subscribe(function(isPerson) {
console.info('isPerson', isPerson);
}));
}
});
var person = new Person();
person.dispose(); // the subscriptions tracked using disposeWithInstance are now also disposed of with the instance


public class Coordinate
extends java.lang.Object
implements java.lang.Comparable, java.lang.Cloneable, java.io.Serializable
Point
, which is a subclass of Geometry
.
Unlike objects of type Point
(which contain additional
information such as an envelope, a precision model, and spatial reference
system information), a Coordinate
only contains ordinate values
and accessor methods.
Coordinate
s are two-dimensional points, with an additional Z-ordinate.
If an Z-ordinate value is not specified or not defined,
constructed coordinates have a Z-ordinate of NaN
(which is also the value of NULL_ORDINATE
).
The standard comparison functions ignore the Z-ordinate.
Apart from the basic accessor functions, JTS supports
only specific operations involving the Z-ordinate.
| Modifier and Type | Class and Description |
|---|---|
static class |
Coordinate.DimensionalComparator
Compares two
Coordinate s, allowing for either a 2-dimensional
or 3-dimensional comparison, and handling NaN values correctly. |
| Modifier and Type | Field and Description |
|---|---|
static double |
NULL_ORDINATE
The value used to indicate a null or missing ordinate value.
|
double |
x
The x-coordinate.
|
static int |
X
Standard ordinate index values
|
double |
y
The y-coordinate.
|
static int |
Y |
double |
z
The z-coordinate.
|
static int |
Z |
| Constructor and Description |
|---|
Coordinate()
Constructs a
Coordinate at (0,0,NaN). |
Coordinate(Coordinate c)
Constructs a
Coordinate having the same (x,y,z) values as
other . |
Coordinate(double x,
double y)
Constructs a
Coordinate at (x,y,NaN). |
Coordinate(double x,
double y,
double z)
Constructs a
Coordinate at (x,y,z). |
| Modifier and Type | Method and Description |
|---|---|
java.lang.Object |
clone() |
int |
compareTo(java.lang.Object o)
Compares this
Coordinate with the specified Coordinate for order. |
double |
distance(Coordinate c)
Computes the 2-dimensional Euclidean distance to another location.
|
double |
distance3D(Coordinate c)
Computes the 3-dimensional Euclidean distance to another location.
|
boolean |
equalInZ(Coordinate c,
double tolerance)
Tests if another coordinate has the same value for Z, within a tolerance.
|
boolean |
equals(java.lang.Object other)
Returns
true if other has the same values for
the x and y ordinates. |
boolean |
equals2D(Coordinate other)
Returns whether the planar projections of the two
Coordinate s
are equal. |
boolean |
equals2D(Coordinate c,
double tolerance)
Tests if another coordinate has the same values for the X and Y ordinates.
|
boolean |
equals3D(Coordinate other)
Tests if another coordinate has the same values for the X, Y and Z ordinates.
|
double |
getOrdinate(int ordinateIndex)
Gets the ordinate value for the given index.
|
int |
hashCode()
Gets a hashcode for this coordinate.
|
static int |
hashCode(double x)
Computes a hash code for a double value, using the algorithm from
Joshua Bloch's book Effective Java"
|
void |
setCoordinate(Coordinate other)
Sets this
Coordinate s (x,y,z) values to that of other . |
void |
setOrdinate(int ordinateIndex,
double value)
Sets the ordinate for the given index
to a given value.
|
java.lang.String |
toString()
Returns a
String of the form (x,y,z) . |
public static final double NULL_ORDINATE
public static final int X
public static final int Y
public static final int Z
public double x
public double y
public double z
public Coordinate(double x, double y, double z)
Coordinate
at (x,y,z).x
- the x-valuey
- the y-valuez
- the z-valuepublic Coordinate()
Coordinate
at (0,0,NaN).public Coordinate(Coordinate c)
Coordinate
having the same (x,y,z) values as
other
.c
- the Coordinate
to copy.public Coordinate(double x, double y)
Coordinate
at (x,y,NaN).x
- the x-valuey
- the y-valuepublic void setCoordinate(Coordinate other)
Coordinate
s (x,y,z) values to that of other
.other
- the Coordinate
to copypublic double getOrdinate(int ordinateIndex)
X
, Y
, and Z
.ordinateIndex
- the ordinate indexjava.lang.IllegalArgumentException
- if the index is not validpublic void setOrdinate(int ordinateIndex, double value)
X
, Y
, and Z
.ordinateIndex
- the ordinate indexvalue
- the value to setjava.lang.IllegalArgumentException
- if the index is not validpublic boolean equals2D(Coordinate other)
Coordinate
s
are equal.other
- a Coordinate
with which to do the 2D comparison.true
if the x- and y-coordinates are equal; the
z-coordinates do not have to be equal.public boolean equals2D(Coordinate c, double tolerance)
other
- a Coordinate
with which to do the 2D comparison.other
is a Coordinate
with the same values for X and Y.public boolean equals3D(Coordinate other)
other
- a Coordinate
with which to do the 3D comparison.other
is a Coordinate
with the same values for X, Y and Z.public boolean equalInZ(Coordinate c, double tolerance)
c
- a coordinatetolerance
- the tolerance valuepublic boolean equals(java.lang.Object other)
true
if other
has the same values for
the x and y ordinates.
Since Coordinates are 2.5D, this routine ignores the z value when making the comparison.equals
in class java.lang.Object
other
- a Coordinate
with which to do the comparison.true
if other
is a Coordinate
with the same values for the x and y ordinates.public int compareTo(java.lang.Object o)
Coordinate
with the specified Coordinate
for order.
This method ignores the z value when making the comparison.
Returns:
compareTo
in interface java.lang.Comparable
o
- the Coordinate
with which this Coordinate
is being comparedCoordinate
is less than, equal to, or greater than the specified Coordinate
public java.lang.String toString()
String
of the form (x,y,z) .toString
in class java.lang.Object
String
of the form (x,y,z)public java.lang.Object clone()
clone
in class java.lang.Object
public double distance(Coordinate c)
c
- a pointpublic double distance3D(Coordinate c)
c
- a coordinatepublic int hashCode()
hashCode
in class java.lang.Object
public static int hashCode(double x)


The last few Future Friday’s, I’ve focused on Web 3. I explored how the blockchain is paving the way for a decentralized networks, and how those networks can be developed and governed using crypto tokens as incentives.
Today I want to cover some details of how data is transmitted and how people reach agreement within a decentralized world using Blockchains.
In order for a decentralized world to work, there needs to be a few elements in place:
- The ability for one node in a network to reliably send messages to another without a central party - a reliable and trustworthy method of peer-to-peer messaging.
- The ability for multiple computers to agree on the validity of a transaction, a problem known as consensus. A transaction can be any blockchain-based transaction - it can be to record the transfer of digital assets like Bitcoin, but also for something like file transfers (as used in IPFS).
Both of these are solved by cryptography.
Peer to peer messaging is done using public-key cryptography and digital signatures. Public Key Cryptography is a cryptographic system that relies on a pair of keys, a secret private key and an ‘open’ public key which is broadcasted out to the network. This system helps ensure the authenticity and integrity of a message by relying on advanced cryptographic techniques. (source)
Agreement on the validity of transaction is done using a consensus algorithm agreed to by all members of the blockchain. This consensus algorithm is used to validate transactions on the chain without needing a central party. There are two forms of conensus (source):
- Permissionless, in which every node in the network participate in consensus procedure, e.g. Bitcoin Blockchain (Proof of Work)
- Permissioned, in which only Selected nodes (validators, e.g. Government or trusted nodes) participate in consensus procedure
Some of most common consensus algorithms being used by different blockchains today are Proof of Work (used by Bitcoin), and Proof of Stake.
- A Proof of Work (PoW), where a node on the network has to solve mathematically complex puzzles on the new block before approving the block to the ledger. After solving the puzzle, the solution is then forwarded to other miners and verified by them before being accepted to their respective copies of the ledger (source).
- Proof of Stake (PoS), in which a node on the network is selected to verify the transaction based on how much token ownership they have.
This is a great article summarizing some of the most common consensus algorithms.
From Web 3 Consensus Mechanisms on the importance of consensus mechanisms.
Consensus mechanisms are a integral to blockchain technology and other distributed systems. They are the basis on which participants of a given network with a range of varied self-interests, and even a mutual distrust for one another, can come to an agreement on the validity of data and transactions. The consensus model implemented by a project, company or team is the heart of its security, communication, and sustainability.


Presently, Pyclamp is not compiled and must therefore be run from source by Python 2 with all dependencies installed:
Pyclamp supports only 64-bit environments. Since there is no official 64-bit version of NumPy for Windows, Pyclamp most easily runs within Linux. If you do not use Linux, you are welcome to try to Pyclamp on your host operating system but it may not work. There are unofficial 64-bit versions of Numpy for Windows which can try to make work with Pyclamp. If this is all too much for Windows users, then I might be tempted a compile a stand-alone executable for Windows if enough interest is out there, so please email if you’d like me to do this. If you’re Apple user, then life is probably easier for you installing Pyclamp but I’m not in much of a position to help because I’ve never touched an Apple.
Since there are many different flavours of Linux, it is difficult to provide a comprehensive and accurate description of how the dependencies of Pyclamp should be installed. Many popular Linux distributions come with package managers that will allow you to install the dependencies safely from trusted repositories. For various reasons, it is possible your distribution does not include all the dependencies, particularly PyQt, PyQtGraph, and most elusive of all, the python-opengl dependency. If web-searches for these packages are not sufficient for you to be able to install them, then your choice of Linux distribution might be a bit tricky to accommodate. In such cases, you should consult your local Linux guru.
I haven’t yet site-packaged Pyclamp as a setup.py-installable Python package, so installation is nothing more than copying the unzipped three directories ‘quantal’, ‘gen’, and ‘pyclamp’ into a destination directory of your choice. The graphical user interface necessitates Pyclamp to be run within X and not from a virtual console. The workng directory for running Pyclamp has to ‘.../pyclamp/’. Pyclamp can be started by navigating to the ‘pyclamp’ directory and running (within Linux) the ‘pyclamp’ file. Or you can run it from command line in one of three ways:
Method 1:
Method 2:
Method 3:
If all methods fail, you probably have a missing or broken dependency. In such cases, an informative error message will hopefully guide you as to the cause.


Sample application demoing app engine for AI for social good. Using public data set from `Our world in Data` at 'https://raw.githubusercontent.com/owid/co2-data/master/owid-co2-data.csv'


These free mindfulness sessions are led by experienced teachers, and offer an opportunity to refresh and sustain your practice. Join us.
Since the Covid-19 outbreak we are offering most of our mindfulness drop-ins via Zoom. All drop-ins are free of charge. Please note these sessions are for adults. Drop in sessions for young people are held separately and details of these can be found on the Child and Adolescent page of this website.
{{ current.name }}
{% if current.description_markdown %}{{ current.description_markdown | markdownify }}
{% endif %}-
{% for event in current.drop-in %}
-
{% if event.event_date %}
{{ event.event_date | date: "%-d %B" }}
{% endif %} {% if event.organiser %} {{ event.organiser }}
{% endif %} {% if event.description_markdown %}{{ event.description_markdown | markdownify }}
{% endif %}
{% endfor %}


ProjectIt MetaModel
This Meta module is a helper module that supports users to specify the language structure for a TypeScript implementation.
As of now, this is unfinished work.
This Meta module is a helper module that supports users to specify the language structure for a TypeScript implementation.
As of now, this is unfinished work.


In graphics we usually use a camera analogy, i.e., the viewer, located at the View Reference Point (VRP), observes the scene through a camera and can move around the scene. This is accomplished by defining a viewing coordinate system (VCS) (left handed) which has the position and orientation of the camera. Then we align the VCS with the world coordinate system (WCS), creating a viewing transformation matrix. This matrix is then applied to all the objects in the scene which moves them into the proper position as seen from the VRP. We will assume the world coordinate system is right handed.
First step : Choosing the VCS origin (in world coordinates). This is the VRP, that is, the position of the camera (observer). Next, we define a projection plane (view plane or image plane). Choose a view plane normal vector, N which determines the positive Z axis direction. Next choose a view up vector, V which determines the positive y axis direction. We are through since the positive U (X) axis is orthogonal to the V (Y) and N (Z) axis.
Now that we have defined a VCS (left handed) we must perform a coordinate transformation to align the WCS with the VCS.
A problem with the previous method is that it is not easy for the user to choose N and an orthogonal vector, V. So we will look at an alternative method of determining the Viewing Coordinate System. We ask the viewer to choose the VRP (viewers position), a Focus Point (FP), i.e. center of focus or center of attention, and an up point (UP). Then we compute the Eye Vector (EV) which is the vector from the VRP to the Focus Point. We normalize EV and this becomes N, the normal to the view plane , which is the Z axis of the VCS. The length of EV can be used as the view plane distance, i.e., the distance between the VRP and the View Plane.
Now compute the vector from the VRP to the Up Point. This vector (UV) is not necessarily orthogonal to N so we must construct the up vector which is orthogonal to N. This is given by the following:
Now, normalize V1 and get V. |
The third axis U = N × V (since the VCS is left handed). The viewing transformation M transforms objects described in the WCS into the VCS. It is given as:
| R | 0 | M = | ---|-----| | T | 1 |
Where R = the rotational component, i.e., it rotates the VCS into
alignment with the WCS, and T is the translation component, i.e. it
translates the VRP into the origin. So we now have two R3 spaces with
orthonormal bases X , Y, Z and U, V, N. So we want to find the rotational
matrix R, which transforms from one vector space to the other. That is, to
transform a point P from UVN space to XYZ space we multiply by R.R × Puvn => Pxyz Then : u × R = i v × R = j => L × R = I n × R = k |
The rotation transformation aligns n with the -z axis, but then we invert the z axis since are converting from a left handed to a right handed system so the composition of these two transformations maps n into the + z axis ;
| u1 u2 u3 | where L = | v1 v2 v3 | | n1 n2 n3 |
Now L × L-1 = I => R = L-1
Since u, v, n are orthonormal and L is an orthogonal matrix L-1 = LT
(transpose).
| u1 v1 n1 | Therefore R = LT = | u2 v2 n2 | | u3 v3 n3 |
Now M transforms the VRP into the origin of the WCS, so:
So the complete viewing transformation matrix is as follows:
| u1 v1 n1 0 | M =| u2 v2 n2 0 | | u3 v3 n3 0 | |-VRP·u -VRP·v -VRP·n 1 |
We can now apply this matrix, M, to all the objects in the scene and it will orient them in the way we want, i.e., as viewed from the VRP.
Last changed September 30, 1998, G. Scott Owen, owen@siggraph.org


Apple's Astounding Capital Expenditures
October 30, 2013 · 2 minute read · CommentsApple’s most recent 10-K filing with the U.S. Securities and Exchange Commission shows the company has budgeted $11 billion in capital expenditures for fiscal 2014.
This is more than 5 times Apple’s capital expenditure in 2010 and 57 percent more than the $7 billion it spent in 2013.
What is Apple planning to do with all that additional money? According to Horace Dediu perhaps Apple is just conducting business as usual and the increased CAPEX simply reflects potentially higher sales volumes for iOS devices in 2014. He has a chart that tracks capital expenditure against iOS device volume and they track very closely. But I think the relationship may be somewhat coincidental.
Consider Apple’s desire to move away from Samsung. Be it on displays or in chips, I suspect this strategic direction is increasing CAPEX significantly without any corresponding unit sale increases.
I also suspect the new campus has a significant impact. In addition we must consider the data centers Apple has been building over the last 2 years to support it’s cloud services - clearly not production related CAPEX.
Logically a portion of 2014 CAPEX is going to new device development and production - the iPhone 6 will very likely have a new form-factor and design. The iPod line needs a refesh. But the iPad Mini and iPad Air in my opinion will remain as is in 2014. So is the iPhone and iPod enough to drive CAPEX up that strongly? I doubt it.
Earlier this week, Apple Chief Executive Officer Tim Cook said the company is working on new releases in technology categories where it doesn’t yet compete. So perhaps an iWatch or an iTV is what is driving this spend. But maybe there is something really revolutionary coming. Personally I want to be surprised and amazed in 2014 - just like when the original iPhone was introduced back in 20007.


Congratulations on your acceptance! The next step is for you to finish the online training sessions.
These sessions are designed to provide the basic skills and information you need as a health professional to improve disease surveillance not only in your community and country, but also globally.
Once you have successfully completed your training, you will have access to the Epicore platform.
Start the online training.
If at any point you have questions, please do not hesitate to reach out to us at<EMAIL_ADDRESS>We look forward to working with you soon!


{% extends "base.html" %} {% block content %}
Restrictions can be applied to an API token so that it can only be used from JavaScript running on particular pages by requiring that the HTTP 'Referer' header in API requests matches one of the patterns listed here. API tokens with no restrictions can be used from anywhere.
Paterns that don't include a '/' character are compared with the host name component of the referer URL only. Patterns containing at least one '/' are compared with the entire referer URL. Patterns can include shell-style wildcard characters: '*' matches anything (including nothing), '?' matches a single character, '[seq]' matches any character in seq, and '[!seq]' matches any character not in seq. For a literal match, wrap the meta-characters in brackets - for example, '[?]' matches the character '?'.
A pattern must compare exactly (allowing for wildcards) for it to match.
{% if referers %}{% else %}
This token has no restrictions.
{% endif %}{% endblock %}


Apple pushes iOS 13.2.3 to further fix background process bugs
iOS 13’s buggy release continues to get patched up
by Henry BurrelliOS 13.2.3 is now available to the public with compatible iPhones and iPads. As we’ve been reporting, iOS 13 has been quite the buggy release and these point updates are unprecedented in how frequent they are and how much they are supposedly fixing.
Apple’s update list reads:
- Fixes an issue where system search and search within Mail, Files, and Notes might not work
- Addresses an issue where photos, links, and other attachments might not display in the Messages details view
- Fixes an issue that could prevent apps from downloading content in the background
- Resolves issues that may prevent Mail from fetching new messages, and fail to include and quote original message content in Exchange accounts
The update further address the background process issues people have been reporting with iOS 13 – here that is to do with downloading content and fetching emails.
Search within Mail, Files and Notes has been tweaked as well as documented problems with attachments in the Messages app. It’s been less than two weeks since iOS 13.2.2 and the updates will likely keep on coming as we head towards Christmas.
Apple sells a lot of iPhones and iPads in the festive season so it’ll want to make sure people using new gear on the big day aren’t plagued by the same bugs those who are already on iOS 13 are experiencing.


|
||||||||||
| PREV NEXT | FRAMES NO FRAMES |
| Packages that use ussr.physics | |
|---|---|
| ussr.comm | An abstract communications model comprising transmitters, receivers, and packets. |
| ussr.model | An abstract model of a modular robot to be used from the controller. |
| ussr.physics | An abstract model of a physics engine, serves as the interface between physics-engine independent classes and the physics engine. |
| ussr.physics.jme | A physics simulation implementation based on JME (JMonkeyEngine). |
| ussr.physics.jme.actuators | Provides a collection of actuators for the JME physics engine implementation. |
| ussr.physics.jme.connectors | Provides a collection of connectors for the JME physics engine implementation. |
| ussr.physics.jme.robots | Robot implementations for the ussr.physics.jme simulation implementation. |
| ussr.physics.jme.sensors | Provides a collection of sensors for the JME physics engine implementation. |
| ussr.samples | Generic infrastructure for simulations as well as examples of simulations mixing different robots. |
| ussr.samples.atron | Simulation examples based on the ATRON modular self-reconfigurable robot. |
| ussr.samples.atron.natives | ATRON examples based on native (implemented in C) controllers |
| ussr.samples.atron.network | ATRON network controller. |
| ussr.samples.atron.simulations | Concrete examples of ATRON simulations. |
| ussr.samples.mtran | Preliminary simulations based on the M-TRAN modular self-reconfigurable robot |
| ussr.samples.white | Simple and very preliminary example of a reconfigurable robot with hinge-joints at the edges. |
| Classes in ussr.physics used by ussr.comm | |
|---|---|
| PhysicsEntity
Abstract interface for any kind of physics entity, allowing physicsal attributes of the entity to be determined |
| Classes in ussr.physics used by ussr.model | |
|---|---|
| ConnectorBehaviorHandler
For connectors that support it, this interface allows details of the connector behavior to be specified independently of the controller, such as whether to automatically connect when another connector is within connection proximity. |
|
| PhysicsConnector
A simulated physical connector, useable independently of the underlying physics engine. |
|
| PhysicsEntity
Abstract interface for any kind of physics entity, allowing physicsal attributes of the entity to be determined |
|
| PhysicsModuleComponent
A simulated physical module, useable independently of the underlying physics engine. |
|
| PhysicsSimulation
A physics simulation, defined independently of the underlying physics engine. |
|
| PhysicsSimulationHelper
A helper class for physics simulations, containing various utility methods that can be applied to the PhysicsSimulation object associated with this helper. |
| Classes in ussr.physics used by ussr.physics | |
|---|---|
| ConnectorBehaviorHandler
For connectors that support it, this interface allows details of the connector behavior to be specified independently of the controller, such as whether to automatically connect when another connector is within connection proximity. |
|
| ModuleFactory
A module factory creates robot modules in a simulation instance. |
|
| PhysicsEntity
Abstract interface for any kind of physics entity, allowing physicsal attributes of the entity to be determined |
|
| PhysicsObserver
The physics simulation notifies observers (as per the observer design pattern) at each time step, allowing code to potentially be run at every physics step. |
|
| PhysicsParameters
A collection of parameters that describe the physical properties of the simulation. |
|
| PhysicsParameters.Material
Standard materials supported by the physics engine of the simulator |
|
| PhysicsQuaternionHolder
Utility class allowing the physics-engine specific representation of a quaternion generated by the physics engine to be stored at the abstract model level of the software. |
|
| PhysicsSimulation
A physics simulation, defined independently of the underlying physics engine. |
|
| PhysicsSimulation.Handler
An ultra-simple user-input handler |
|
| PhysicsSimulationHelper
A helper class for physics simulations, containing various utility methods that can be applied to the PhysicsSimulation object associated with this helper. |
|
| PhysicsVectorHolder
Utility class allowing the physics-engine specific representation of a vector generated by the physics engine to be stored at the abstract model level of the software. |
|
| SimulationGadget
A simulation gadget is a plugin that allows some aspect of the user interface to be tailored to the specific simulation that is running |
|
| SimulationGadget.Host
The host provides an interface and utility functionality for a simulation gadget |
|
| SimulationGadget.Textual
A textual simulation gadget implements user interactions specified through a textual interface |
| Classes in ussr.physics used by ussr.physics.jme | |
|---|---|
| ModuleFactory
A module factory creates robot modules in a simulation instance. |
|
| PhysicsEntity
Abstract interface for any kind of physics entity, allowing physicsal attributes of the entity to be determined |
|
| PhysicsModuleComponent
A simulated physical module, useable independently of the underlying physics engine. |
|
| PhysicsObserver
The physics simulation notifies observers (as per the observer design pattern) at each time step, allowing code to potentially be run at every physics step. |
|
| PhysicsQuaternionHolder
Utility class allowing the physics-engine specific representation of a quaternion generated by the physics engine to be stored at the abstract model level of the software. |
|
| PhysicsSimulation
A physics simulation, defined independently of the underlying physics engine. |
|
| PhysicsSimulation.Handler
An ultra-simple user-input handler |
|
| PhysicsSimulationHelper
A helper class for physics simulations, containing various utility methods that can be applied to the PhysicsSimulation object associated with this helper. |
|
| PhysicsVectorHolder
Utility class allowing the physics-engine specific representation of a vector generated by the physics engine to be stored at the abstract model level of the software. |
|
| SimulationGadget
A simulation gadget is a plugin that allows some aspect of the user interface to be tailored to the specific simulation that is running |
|
| SimulationGadget.Host
The host provides an interface and utility functionality for a simulation gadget |
| Classes in ussr.physics used by ussr.physics.jme.actuators | |
|---|---|
| PhysicsEntity
Abstract interface for any kind of physics entity, allowing physicsal attributes of the entity to be determined |
| Classes in ussr.physics used by ussr.physics.jme.connectors | |
|---|---|
| ConnectorBehaviorHandler
For connectors that support it, this interface allows details of the connector behavior to be specified independently of the controller, such as whether to automatically connect when another connector is within connection proximity. |
|
| PhysicsConnector
A simulated physical connector, useable independently of the underlying physics engine. |
|
| PhysicsEntity
Abstract interface for any kind of physics entity, allowing physicsal attributes of the entity to be determined |
|
| PhysicsObserver
The physics simulation notifies observers (as per the observer design pattern) at each time step, allowing code to potentially be run at every physics step. |
|
| PhysicsQuaternionHolder
Utility class allowing the physics-engine specific representation of a quaternion generated by the physics engine to be stored at the abstract model level of the software. |
|
| PhysicsSimulation
A physics simulation, defined independently of the underlying physics engine. |
| Classes in ussr.physics used by ussr.physics.jme.robots | |
|---|---|
| ModuleFactory
A module factory creates robot modules in a simulation instance. |
|
| PhysicsSimulation
A physics simulation, defined independently of the underlying physics engine. |
| Classes in ussr.physics used by ussr.physics.jme.sensors | |
|---|---|
| PhysicsEntity
Abstract interface for any kind of physics entity, allowing physicsal attributes of the entity to be determined |
| Classes in ussr.physics used by ussr.samples | |
|---|---|
| PhysicsSimulation
A physics simulation, defined independently of the underlying physics engine. |
| Classes in ussr.physics used by ussr.samples.atron | |
|---|---|
| PhysicsObserver
The physics simulation notifies observers (as per the observer design pattern) at each time step, allowing code to potentially be run at every physics step. |
|
| PhysicsSimulation
A physics simulation, defined independently of the underlying physics engine. |
| Classes in ussr.physics used by ussr.samples.atron.natives | |
|---|---|
| PhysicsObserver
The physics simulation notifies observers (as per the observer design pattern) at each time step, allowing code to potentially be run at every physics step. |
|
| PhysicsSimulation
A physics simulation, defined independently of the underlying physics engine. |
| Classes in ussr.physics used by ussr.samples.atron.network | |
|---|---|
| PhysicsObserver
The physics simulation notifies observers (as per the observer design pattern) at each time step, allowing code to potentially be run at every physics step. |
| Classes in ussr.physics used by ussr.samples.atron.simulations | |
|---|---|
| PhysicsObserver
The physics simulation notifies observers (as per the observer design pattern) at each time step, allowing code to potentially be run at every physics step. |
|
| PhysicsSimulation
A physics simulation, defined independently of the underlying physics engine. |
| Classes in ussr.physics used by ussr.samples.mtran | |
|---|---|
| PhysicsObserver
The physics simulation notifies observers (as per the observer design pattern) at each time step, allowing code to potentially be run at every physics step. |
|
| PhysicsSimulation
A physics simulation, defined independently of the underlying physics engine. |
| Classes in ussr.physics used by ussr.samples.white | |
|---|---|
| ModuleFactory
A module factory creates robot modules in a simulation instance. |
|
| PhysicsObserver
The physics simulation notifies observers (as per the observer design pattern) at each time step, allowing code to potentially be run at every physics step. |
|
| PhysicsSimulation
A physics simulation, defined independently of the underlying physics engine. |
|
||||||||||
| PREV NEXT | FRAMES NO FRAMES |


head_ref_force_pushed
by Christina Chortaria at 2022-01-14 02:22:08.head_ref_force_pushed
by Christina Chortaria at 2022-01-14 21:42:02.head_ref_force_pushed
by Christina Chortaria at 2022-01-14 22:52:05.We should hold off on this ticket until contributors have had a chance to refresh Getty data, which should happen within the next week or so.
unlabeled
by Kate Lynch at 2022-01-14 14:56:48.unassigned
by Shaun Ellis at 2022-01-14 20:22:24.labeled
by James R. Griffin III at 2022-01-14 20:47:39.labeled
by James R. Griffin III at 2022-01-14 20:47:39.labeled
by James R. Griffin III at 2022-01-14 20:47:39.assigned
by James R. Griffin III at 2022-01-14 20:47:40.There were some additional synchronization issues which arose which required the following:
update workflowitem set state=3 from (select w.item_id from metadatavalue as v inner join workflowitem as w on v.resource_id=w.item_id where v.text_value like '%Final published version.%' and w.state=3) as subquery where workflowitem.item_id=subquery.item_id;
As reported by Hannah, this database update alone was not sufficient, as the following was discovered:
There are two records that were in Yuan's task pool which have retained the "Initial Review" Label. Here are the titles... This first one should be "Needs Reviewed" see: Individual and Combined Roles of the Master Regulators AphA and LuxR in Control of the Vibrio harveyi Quorum-Sensing Regulon. This second one should be "Reviewed" see: Phase locking of a semiconductor double-quantum-dot single-atom maser Liu, Y-Y; Hartke, TR; Stehlik, J; Petta, Jason R.
I am finding the following in response to a database query:
select workflow_id,item_id,collection_id,state,owner from workflowitem where state=1;
workflow_id | item_id | collection_id | state | owner
-------------+---------+---------------+-------+-------
2663 | 2763 | 51 | 1 |
1476 | 1578 | 46 | 1 |
@jrgriffiniii I'm sorry to report we are experiencing new issues with the task labels that may be related to this and issue #559.
The labels in the task pool are currently incorrectly assigned. Please see the image which shows many of the task pool records as "reviewed" and many of these are not yet in the review stage. Only the records with the metadata for "version" have been reviewed. I'm available to Zoom if you would like a walk-thru for what we are experiencing.
closed
by James R. Griffin III at 2022-01-14 15:04:58.reopened
by James R. Griffin III at 2022-01-14 16:14:06.mentioned
by James R. Griffin III at 2022-01-14 20:49:48.subscribed
by James R. Griffin III at 2022-01-14 20:49:48.labeled
by Chun Ly at 2022-01-14 21:19:30.labeled
by Chun Ly at 2022-01-14 21:20:27.labeled
by Chun Ly at 2022-01-14 21:20:27.labeled
by Chun Ly at 2022-01-14 21:20:27.labeled
by Chun Ly at 2022-01-14 21:21:19.labeled
by Eliot Jordan at 2022-01-14 18:44:05.labeled
by Eliot Jordan at 2022-01-14 18:49:34.renamed
by Eliot Jordan at 2022-01-14 18:50:17.labeled
by Eliot Jordan at 2022-01-14 18:55:03.closed
by Eliot Jordan at 2022-01-14 18:55:37.labeled
by Eliot Jordan at 2022-01-14 18:50:50.labeled
by Eliot Jordan at 2022-01-14 18:59:40.labeled
by Eliot Jordan at 2022-01-14 19:13:37.renamed
by Eliot Jordan at 2022-01-14 19:14:06.labeled
by Eliot Jordan at 2022-01-14 19:15:48.labeled
by Eliot Jordan at 2022-01-14 19:17:14.labeled
by Eliot Jordan at 2022-01-14 19:17:50.Related to #4868.
referenced
by None at 2022-01-14 19:39:22.merged
by None at 2022-01-14 19:39:22.closed
by None at 2022-01-14 19:39:22.head_ref_deleted
by None at 2022-01-14 19:39:23.Two questions:
#primary_file
Probably related to https://github.com/pulibrary/figgy/issues/4761. There's a branch linked in that ticket that starts things.
unlabeled
by Eliot Jordan at 2022-01-14 20:18:23.unassigned
by Eliot Jordan at 2022-01-14 20:18:44.Generate a CSV with all the resources that have multiple parents with the following info:
ResourceID, BibID, Title, Parent1ID, Parent1Title, Parent2ID, Parent2Title, CorrectParent, where CorrectParent is blank. Then we can ask @kelea99 to fill it out and fix them up.
mentioned
by Kim Leaman at 2022-01-14 20:26:05.subscribed
by Kim Leaman at 2022-01-14 20:26:05.assigned
by Eliot Jordan at 2022-01-14 20:26:19.renamed
by Trey Pendragon at 2022-01-14 20:37:58.assigned
by Trey Pendragon at 2022-01-14 21:00:05.closed
by Francis Kayiwa at 2022-01-14 21:14:52.referenced
by Francis Kayiwa at 2022-01-14 21:14:53.labeled
by Eliot Jordan at 2022-01-14 19:23:19.closed
by None at 2022-01-14 21:38:41.closed
by None at 2022-01-14 21:38:41.@hackartisan Yes, individual rasters can (and should) be served out using TiTiler WMTS and XYZ endpoints. I created an issue for the tile_layer bit: https://github.com/pulibrary/figgy/issues/4897
Rediscovered it as I was working this PR and it made sense to get rid of at the same time.
mentioned
by None at 2022-01-14 19:25:47.subscribed
by None at 2022-01-14 19:25:48.review_requested
by Eliot Jordan at 2022-01-14 19:35:00.referenced
by None at 2022-01-14 21:38:41.merged
by None at 2022-01-14 21:38:41.closed
by None at 2022-01-14 21:38:41.head_ref_deleted
by None at 2022-01-14 21:38:42.closed
by None at 2022-01-14 15:41:26.Coverage remained the same at 96.74% when pulling 4c223157bf1d3124b1e9bb88007ed9d1b8dda945 on 2821-facet-link into f6ffd6bb38a10ef836fd6699cdbd43221c6a94e7 on main.
@carolyncole I updated the PR. When tabkey or when letting screen reader to read, it announces if the button is collapsed or expanded. When keydown 'Enter' or Space' it collapses and expands accordingly. I also added role='button' in the facets layout. I commented the other code in case we want to use .js for the role="button". I also added a feature test to show the toggle of aria-expanded attribute.
https://user-images.githubusercontent.com/9905193/149433961-98e4e417-ef90-4eba-8fa3-f7d9d45e28d7.mov
head_ref_force_pushed
by Christina Chortaria at 2022-01-14 01:02:24.head_ref_force_pushed
by Christina Chortaria at 2022-01-14 01:07:51.mentioned
by None at 2022-01-14 01:13:28.subscribed
by None at 2022-01-14 01:13:28.deployed
by None at 2022-01-14 14:51:26.referenced
by None at 2022-01-14 15:41:26.merged
by None at 2022-01-14 15:41:26.closed
by None at 2022-01-14 15:41:26.head_ref_deleted
by None at 2022-01-14 15:41:27.Coverage remained the same at 96.74% when pulling 78f44dc9bbc4b115b1fbe69946329e4fa5e3ab01 on accessible-select into 17c660a6c48e422d51d9505ee0c081b61e4e6509 on main.
@christinach good catch. I removed the bootstrap styling...
head_ref_force_pushed
by None at 2022-01-14 18:17:19.deployed
by None at 2022-01-14 18:24:19.head_ref_force_pushed
by None at 2022-01-14 20:04:20.mentioned
by Christina Chortaria at 2022-01-14 20:50:51.subscribed
by Christina Chortaria at 2022-01-14 20:50:51.Coverage increased (+0.009%) to 96.749% when pulling 7c8a8a4b0ffa3636b4d03e85828fa11626e15931 on 1750-bibdata-lang-attribute into 17c660a6c48e422d51d9505ee0c081b61e4e6509 on main.
head_ref_force_pushed
by Christina Chortaria at 2022-01-14 23:00:53.referenced
by None at 2022-01-14 19:18:57.merged
by None at 2022-01-14 19:18:58.closed
by None at 2022-01-14 19:18:58.closed
by None at 2022-01-14 19:18:58.As @kayiwa was describing, this may well be related to the potential issues which arise due to perceived DDOS attacks upon the OIT DNS servers (this is due to the number of requests made, frequently, by figgy
servers).
Ah, thanks @jrgriffiniii and @kayiwa for the background. Since the existing figgy machines are set to <IP_ADDRESS>, we're clearly not mimicking DDOS attacks on OIT any more. I'll open a PR to update the bind9 role for future VM builds.
mentioned
by Francis Kayiwa at 2022-01-14 15:13:51.subscribed
by Francis Kayiwa at 2022-01-14 15:13:51.mentioned
by Francis Kayiwa at 2022-01-14 15:55:22.subscribed
by Francis Kayiwa at 2022-01-14 15:55:22.mentioned
by James R. Griffin III at 2022-01-14 15:55:22.subscribed
by James R. Griffin III at 2022-01-14 15:55:22.closed
by Francis Kayiwa at 2022-01-14 21:14:52.This PR also adds a tag for updating the NginxPlus configuration, so we can add new VMs into the ecosystem without re-running the entire role. See #2647 for another example of adding tags.
Related to https://github.com/pulibrary/figgy/pull/4887.
head_ref_force_pushed
by Alicia Cozine at 2022-01-14 19:10:08.head_ref_force_pushed
by Alicia Cozine at 2022-01-14 19:20:05.referenced
by Francis Kayiwa at 2022-01-14 21:14:52.merged
by Francis Kayiwa at 2022-01-14 21:14:52.closed
by Francis Kayiwa at 2022-01-14 21:14:52.head_ref_deleted
by Francis Kayiwa at 2022-01-14 21:14:53.referenced
by None at 2022-01-14 17:39:37.merged
by None at 2022-01-14 17:39:37.closed
by None at 2022-01-14 17:39:37.head_ref_deleted
by None at 2022-01-14 17:39:38.labeled
by None at 2022-01-13 23:40:26.labeled
by None at 2022-01-13 23:40:26.labeled
by Trey Pendragon at 2022-01-14 17:09:21.labeled
by Trey Pendragon at 2022-01-14 17:11:17.unlabeled
by Trey Pendragon at 2022-01-14 17:11:20.labeled
by Trey Pendragon at 2022-01-14 17:15:46.closed
by Trey Pendragon at 2022-01-14 17:17:27.closed
by Trey Pendragon at 2022-01-14 17:18:19.With better relevancy we decided to keep it grouped by collection. Similar to #632
We want to test this. Similar to #632
reopened
by Trey Pendragon at 2022-01-14 17:19:41.We're going to wait for this to be confusing if it turns out to be.
closed
by Trey Pendragon at 2022-01-14 17:23:04.renamed
by Trey Pendragon at 2022-01-14 17:28:53.closed
by Trey Pendragon at 2022-01-14 17:35:52.closed
by Trey Pendragon at 2022-01-14 17:36:59.closed
by Trey Pendragon at 2022-01-14 17:39:16.Example: "Princeton University Library: Manuscripts Division". When we change this ping @magibney to give them a heads up.
mentioned
by Michael Gibney at 2022-01-14 17:41:06.subscribed
by Michael Gibney at 2022-01-14 17:41:06.We haven't seen this in a while, seems like a JS malfunction that has since been fixed.
closed
by Trey Pendragon at 2022-01-14 17:42:25.closed
by Trey Pendragon at 2022-01-14 17:44:21.We've changed the logic so it'll always ask for a viewer. Closing.
closed
by Trey Pendragon at 2022-01-14 17:45:13.Will need to replicate.
closed
by Trey Pendragon at 2022-01-14 17:46:44.labeled
by None at 2022-01-14 17:48:25.labeled
by None at 2022-01-14 17:49:16.For example in https://findingaids.princeton.edu/catalog/C0377?expanded=true it should show each box and folder number it's in.
renamed
by Trey Pendragon at 2022-01-14 17:53:11.Closing this because I can't replicate in the UI.
labeled
by Trey Pendragon at 2022-01-14 17:38:55.labeled
by Trey Pendragon at 2022-01-14 17:38:59.closed
by Trey Pendragon at 2022-01-14 19:58:54.Resolve this when we determine if this always happens, and if it does always happen find a way to prevent it from happening.
Maybe this task is being run on multiple boxes?
All uses of .
were changed to -
Closed and connected to https://github.com/pulibrary/pulfalight/issues/799
labeled
by Trey Pendragon at 2022-01-14 17:48:11.labeled
by Trey Pendragon at 2022-01-14 17:48:14.closed
by Trey Pendragon at 2022-01-14 20:40:23.labeled
by Trey Pendragon at 2022-01-14 20:40:31.labeled
by Eliot Jordan at 2022-01-14 19:05:17.labeled
by Eliot Jordan at 2022-01-14 19:07:08.I currently have the following design implemented for the file selection interface:
One should please note that Departments can be updated using the "Settings" tab, and within this, the "Configurable Settings" tab:
assigned
by Bess Sadler at 2022-01-14 13:55:07.closed
by Bess Sadler at 2022-01-14 17:56:26.renamed
by Kevin Reiss at 2022-01-14 20:45:46.labeled
by None at 2022-01-14 01:06:15.labeled
by None at 2022-01-14 01:06:15.Resolved: Dataspace is back up in d1081a9
.
labeled
by Francis Kayiwa at 2022-01-14 00:54:44.labeled
by Francis Kayiwa at 2022-01-14 00:54:44.locked
by Francis Kayiwa at 2022-01-14 00:54:45.closed
by Francis Kayiwa at 2022-01-14 01:59:14.


Throttling a flow can allow us to control the rate at which we send requests to a target. This is very important as it allows us to meet the processing rate of the target system and essentially prevent our ESB from hammering a system with requests. The throttle limit can be set in a flow and as such will allow us to dictate a different speed for different targets.
Here is an example of our Async Ping flow being throttled.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<camelContext trace="false" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="api://execute/skeleton/v0/asyncping"/>
<throttle timePeriodMillis="1000" asyncDelayed="true">
<simple>'2'</simple>
<to uri="rest://remote_system_api/sendPingMessage">
<description>Throttled async ping flow which will only send 2 message per second. </description>
</to>
</throttle>
</route>
</camelContext>
</beans>
This will send 2 messages per second to the target system. Note that in a broadcast we can throttle at different rates to different remote systems.


by Dzmitry Gerasimov
<IP_ADDRESS>
'AT*REF=0,512\r' +
'AT*PCMD=1,0,0,0,0,0\r'
According to tests, a satisfying control of the AR.Drone is reached by sending the ATcommands every 30 ms for smooth drone movements. To prevent the drone from considering the WIFI connection as lost, two consecutive commands must be sent within less than 2 seconds.
dgram = require 'dgram'
socket = dgram.createSocket 'udp4'
seq = 0
flying = false
emergency = false
setInterval ->
ref = (flying << 9) | (emergency << 8)
commands = [
"AT*REF=#{seq++},#{ref}"
"AT*PCMD=#{seq++},0,0,0,0,0"
].join('\r') + '\r'
buffer = new Buffer commands
socket.send buffer, 0, buffer.length, 5556, '<IP_ADDRESS>'
, 30
var arDrone = require('ar-drone');
var client = arDrone.createClient();
client.takeoff();
client
.after(5000, function() {
this.clockwise(0.5);
})
.after(3000, function() {
this.stop();
this.land();
});
var arDrone = require('ar-drone');
var client = arDrone.createClient();
client.createRepl();
var arDrone = require('ar-drone');
var client = arDrone.createClient();
client.on('navdata', console.log);


Welcome to my Portfolio!
Name: Tejas Vajjhala
Major: Computer Science
Team: 204
Role: Team Lead
Language of Expertise: C++, Dart, Flutter, Java, Node.js, PHP, HTML, MySQL, Unix, Network Security
Hobbies: Music Production
Email<EMAIL_ADDRESS>Github: tvajjhala
Future Goal: Build successful businesses


We have developed specialized routines to make use of NVIDIA CUDA GPU processing to speed up some operations (e.g. FIR filtering) by up to 10x. If you want to use NVIDIA CUDA, you should install:
For example, on Ubuntu 15.10, a combination of system packages and git
packages can be used to install the CUDA stack:
# install system packages for CUDA
$ sudo apt-get install nvidia-cuda-dev nvidia-modprobe
# install PyCUDA
$ git clone http://git.tiker.net/trees/pycuda.git
$ cd pycuda
$ ./configure.py --cuda-enable-gl
$ git submodule update --init
$ make -j 4
$ python setup.py install
# install skcuda
$ cd ..
$ git clone https://github.com/lebedov/scikit-cuda.git
$ cd scikit-cuda
$ python setup.py install
To initialize mne-python cuda support, after installing these dependencies and running their associated unit tests (to ensure your installation is correct) you can run:
$ MNE_USE_CUDA=true MNE_LOGGING_LEVEL=info python -c "import mne; mne.cuda.init_cuda()"
Enabling CUDA with 1.55 GB available memory
If you have everything installed correctly, you should see an INFO-level log message telling you your CUDA hardware’s available memory. To have CUDA initialized on startup, you can do:
>>> mne.utils.set_config('MNE_USE_CUDA', 'true')
You can test if MNE CUDA support is working by running the associated test:
$ nosetests mne/tests/test_filter.py
If MNE_USE_CUDA=true
and all tests pass with none skipped, then
MNE-Python CUDA support works.
In IPython, we strongly recommend using the Qt matplotlib backend for fast and correct rendering:
$ ipython --matplotlib=qt
On Linux, for example, QT is the only matplotlib backend for which 3D rendering will work correctly. On Mac OS X for other backends certain matplotlib functions might not work as expected.
To take full advantage of MNE-Python’s visualization capacities in combination with IPython notebooks and inline displaying, please explicitly add the following magic method invocation to your notebook or configure your notebook runtime accordingly:
In [1]: %matplotlib inline
If you use another Python setup and you encounter some difficulties please report them on the MNE mailing list or on github to get assistance.
If you run into trouble when visualizing source estimates (or anything else
using mayavi), you can try setting the ETS_TOOLKIT
environment variable:
>>> import os
>>> os.environ['ETS_TOOLKIT'] = 'qt4'
>>> os.environ['QT_API'] = 'pyqt'
This will tell Traits that we will use Qt with PyQt bindings.
If you get an error saying:
ValueError: API 'QDate' has already been set to version 1
you have run into a conflict with Traits. You can work around this by telling the interpreter to use QtGui and QtCore from pyface:
>>> from pyface.qt import QtGui, QtCore
This line should be added before any imports from mne-python.
For more information, see http://docs.enthought.com/mayavi/mayavi/building_applications.html.


Library example_drinker_theorem
Back to Coq Main Page
This example included in the official
Coq documentation: see
Paradoxes
of classical predicate calculus.
In fact, it is not a paradox, but rather simple theorem.
It sounds unusual, because most if-then statements usually
mean some causal relationship between the condition and the conclusion.
In the drinker theorem there is no such relationship: We do not
need any assumptions on how one person's drinking affects what
other people do.
Predicate Logic: Drinker's Theorem
"In any nonempty bar there is a person such that, if s/he drinks, then everyone else in that bar also drinks."See Wikipedia: Drinker Paradox for a longer discussion.
Human-readable Proof
We consider two cases.- If we assume that everyone is drinking, then select anybody (note that the bar is nonempty). The conclusion of the theorem will be true.
- If there are non-drinking people in the bar, then select anyone among them. In this case the condition is wrong: the person we selected does NOT drink. Therefore the whole implication will be also true, since false implies anything.
Computer-verified Proof
Section drinker_lemma.
Denote D - the set of all people in the bar;
P - drinker predicate (takes value "true" for those
who drink, takes value "false" otherwise).
There is at least one person in the bar, denote it by d,
we do not know, if d drinks or not.
Variable D: Set.
Variable P: D -> Prop.
Variable d: D.
Axiom ExcludedMiddle: forall A:Prop, A \/ ~ A.
Lemma drinker: exists x:D, P x -> forall x:D, P x.
Proof.
elim (ExcludedMiddle (exists x, ~ P x)).
intros (Tom, Tom_does_not_drink).
exists Tom.
intro Tom_drinks.
contradiction.
intro No_nondrinker.
exists d.
intro d_drinks.
intro Joe.
elim (ExcludedMiddle (P Joe)).
trivial.
intro Joe_does_not_drink.
absurd (exists x, ~ P x).
exact No_nondrinker.
exists Joe.
exact Joe_does_not_drink.
Qed.
End drinker_lemma.


Context FlashText (GitHub, algorithm) uses tries to identify strings faster than regular expressions. The authors of FlashText chose a trie over regular expressions so that the time needed for to locate or replace a keyword did not increase with the size of the document. I think FlashText could be useful for keyword retrieval in Psychic Llama, the identification of KOLs, or my investigation of DNP doses mentioned online.
Introduction
A trie is a tree whose nodes store letters. One can re_trie_ve tokens from the trie by traversing a certain path. A word made of n letters is represented by a trie of depth n. Each level has all the letters needed to represent the tokens of interest. This, as an aside, makes tries a natural source for text for autocompletes.
(I first thought each node would need 26 children, but I then realized that not all letter combinations are possible.) The user, moreover, is likely to be intereted in a subset of all possible combinations of letters.
class TrieNode(object):
def __init__(self, symbol=None, alphabet_length=26):
self.symbol= symbol
self.children = [None]*alphabet_length
//Implicit coding of {0:A, 1:B,...}
We can also add a counter to identify frequently used nodes.
self.counter = 0
The root of a trie contains references to its chlidren. It is otherwise empty.
root = TrieNode(value = "")
We add a node to a trie by starting at the root, and successively adding characters that do not appear in a branch.
def add(root, token):
node = root // set current node to root
for symbol in token:
found = False //Cannot find anything in root. It has empty value.
for child in node.children:
while not found:
if child.symbol == symbol:
child.counter += 1
node = child
//Sequence does not exist in trie
if not found:
new_node = TrieNode(symbol=symbol)
node.children.append(new_node)
node = new_node
We traverse the trie (retrieve a string) by:
def find(root, prefix):
node = root
if not root.children: #Cannot traverse an empty trie
return (False,0)
for symbol in prefix:
found = False
for child in node.children:
while not found:
if child.symbol == symbol:
found = True
node = child
if not found:
return (False,0)
Production Notes