var $ = {
crudify: function (store, query, crud)
{
if (null == crud)
{
crud = query;
query = store;
store = null;
}
if (store)
{
query = store.query(query);
}
query.observe(function (row, deleteIndex, insertIndex)
{
var del = (0 <= deleteIndex), ins = (0 <= insertIndex);
!del && ins && crud.c && crud.c(row);
del && ins && crud.u && crud.u(row);
del && !ins && crud.d && crud.d(row);
}, !!crud.u);
},
get : function ( item, keys )
{
var i, j;
for ( i = 0, j = keys.length; i < j; i++ )
{
item = item[ keys[ i ] ];
if ( undefined === item )
{
break;
}
}
return item;
},
set : function ( item, keys, value )
{
var i, j, key;
for ( i = 0, j = keys.length - 1; i <= j; i++ )
{
key = keys[ i ];
item = item[ key ] = ( i === j ) ? value : ( item[ key ] || [] );
}
return value;
},
delay : function ( timeout, id, callback )
{
this.delays = this.delays || [];
var delay = this.delays[ id ];
if ( delay )
{
clearTimeout ( delay );
}
delay = setTimeout ( callback, timeout );
this.delays[ id ] = delay;
},
range : function ( min, max )
{
var result = [];
while ( min <= max )
{
result.push ( min++ );
}
return result;
}
};
var array = {
every: function (array, test)
{
for (var i = 0; i < array.length; i++)
{
if (!test(array[i], i, array))
return false;
}
return true;
},
filter: function (array, test)
{
var result = [];
for (var i = 0; i < array.length; i++)
{
test(array[i], i, array) && result.push(array[i]);
}
return result;
},
map: function (array, mapper)
{
var result = [];
for (var i = 0; i < array.length; i++)
{
result.push(mapper(array[i], i, array));
}
return result;
},
forEach: function (array, mapper)
{
for (var i = 0; i < array.length; i++)
{
mapper(array[i], i, array);
}
}
};
var lang = {
mixin: function (to, from)
{
for (var key in from)
{
if (from.hasOwnProperty(key))
{
to[key] = from[key];
}
}
return to;
}
};
var string = {
substitute: function (pattern, map)
{
for (var key in map)
{
if (map.hasOwnProperty(key))
{
pattern = pattern.replace("${" + key + "}", map[key]);
}
}
return pattern;
}
};