This app provides monitoring and information features for the common freifunk user and the technical stuff of a freifunk community.
Code base is taken from a TUM Practical Course project and added here to see if Freifunk Altdorf can use it.
https://www.freifunk-altdorf.de
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
5.3 KiB
159 lines
5.3 KiB
'use strict'; |
|
var $ = require('./$') |
|
, hide = require('./$.hide') |
|
, redefineAll = require('./$.redefine-all') |
|
, ctx = require('./$.ctx') |
|
, strictNew = require('./$.strict-new') |
|
, defined = require('./$.defined') |
|
, forOf = require('./$.for-of') |
|
, $iterDefine = require('./$.iter-define') |
|
, step = require('./$.iter-step') |
|
, ID = require('./$.uid')('id') |
|
, $has = require('./$.has') |
|
, isObject = require('./$.is-object') |
|
, setSpecies = require('./$.set-species') |
|
, DESCRIPTORS = require('./$.descriptors') |
|
, isExtensible = Object.isExtensible || isObject |
|
, SIZE = DESCRIPTORS ? '_s' : 'size' |
|
, id = 0; |
|
|
|
var fastKey = function(it, create){ |
|
// return primitive with prefix |
|
if(!isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; |
|
if(!$has(it, ID)){ |
|
// can't set id to frozen object |
|
if(!isExtensible(it))return 'F'; |
|
// not necessary to add id |
|
if(!create)return 'E'; |
|
// add missing object id |
|
hide(it, ID, ++id); |
|
// return object id with prefix |
|
} return 'O' + it[ID]; |
|
}; |
|
|
|
var getEntry = function(that, key){ |
|
// fast case |
|
var index = fastKey(key), entry; |
|
if(index !== 'F')return that._i[index]; |
|
// frozen object case |
|
for(entry = that._f; entry; entry = entry.n){ |
|
if(entry.k == key)return entry; |
|
} |
|
}; |
|
|
|
module.exports = { |
|
getConstructor: function(wrapper, NAME, IS_MAP, ADDER){ |
|
var C = wrapper(function(that, iterable){ |
|
strictNew(that, C, NAME); |
|
that._i = $.create(null); // index |
|
that._f = undefined; // first entry |
|
that._l = undefined; // last entry |
|
that[SIZE] = 0; // size |
|
if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that); |
|
}); |
|
redefineAll(C.prototype, { |
|
// 23.1.3.1 Map.prototype.clear() |
|
// 23.2.3.2 Set.prototype.clear() |
|
clear: function clear(){ |
|
for(var that = this, data = that._i, entry = that._f; entry; entry = entry.n){ |
|
entry.r = true; |
|
if(entry.p)entry.p = entry.p.n = undefined; |
|
delete data[entry.i]; |
|
} |
|
that._f = that._l = undefined; |
|
that[SIZE] = 0; |
|
}, |
|
// 23.1.3.3 Map.prototype.delete(key) |
|
// 23.2.3.4 Set.prototype.delete(value) |
|
'delete': function(key){ |
|
var that = this |
|
, entry = getEntry(that, key); |
|
if(entry){ |
|
var next = entry.n |
|
, prev = entry.p; |
|
delete that._i[entry.i]; |
|
entry.r = true; |
|
if(prev)prev.n = next; |
|
if(next)next.p = prev; |
|
if(that._f == entry)that._f = next; |
|
if(that._l == entry)that._l = prev; |
|
that[SIZE]--; |
|
} return !!entry; |
|
}, |
|
// 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined) |
|
// 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined) |
|
forEach: function forEach(callbackfn /*, that = undefined */){ |
|
var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3) |
|
, entry; |
|
while(entry = entry ? entry.n : this._f){ |
|
f(entry.v, entry.k, this); |
|
// revert to the last existing entry |
|
while(entry && entry.r)entry = entry.p; |
|
} |
|
}, |
|
// 23.1.3.7 Map.prototype.has(key) |
|
// 23.2.3.7 Set.prototype.has(value) |
|
has: function has(key){ |
|
return !!getEntry(this, key); |
|
} |
|
}); |
|
if(DESCRIPTORS)$.setDesc(C.prototype, 'size', { |
|
get: function(){ |
|
return defined(this[SIZE]); |
|
} |
|
}); |
|
return C; |
|
}, |
|
def: function(that, key, value){ |
|
var entry = getEntry(that, key) |
|
, prev, index; |
|
// change existing entry |
|
if(entry){ |
|
entry.v = value; |
|
// create new entry |
|
} else { |
|
that._l = entry = { |
|
i: index = fastKey(key, true), // <- index |
|
k: key, // <- key |
|
v: value, // <- value |
|
p: prev = that._l, // <- previous entry |
|
n: undefined, // <- next entry |
|
r: false // <- removed |
|
}; |
|
if(!that._f)that._f = entry; |
|
if(prev)prev.n = entry; |
|
that[SIZE]++; |
|
// add to index |
|
if(index !== 'F')that._i[index] = entry; |
|
} return that; |
|
}, |
|
getEntry: getEntry, |
|
setStrong: function(C, NAME, IS_MAP){ |
|
// add .keys, .values, .entries, [@@iterator] |
|
// 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11 |
|
$iterDefine(C, NAME, function(iterated, kind){ |
|
this._t = iterated; // target |
|
this._k = kind; // kind |
|
this._l = undefined; // previous |
|
}, function(){ |
|
var that = this |
|
, kind = that._k |
|
, entry = that._l; |
|
// revert to the last existing entry |
|
while(entry && entry.r)entry = entry.p; |
|
// get next entry |
|
if(!that._t || !(that._l = entry = entry ? entry.n : that._t._f)){ |
|
// or finish the iteration |
|
that._t = undefined; |
|
return step(1); |
|
} |
|
// return step by kind |
|
if(kind == 'keys' )return step(0, entry.k); |
|
if(kind == 'values')return step(0, entry.v); |
|
return step(0, [entry.k, entry.v]); |
|
}, IS_MAP ? 'entries' : 'values' , !IS_MAP, true); |
|
|
|
// add [@@species], 23.1.2.2, 23.2.2.2 |
|
setSpecies(NAME); |
|
} |
|
}; |