cryptpad/www/common/worker.bundle.js
2025-03-21 18:07:04 +01:00

36400 lines
1.8 MiB

(function(global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define([ "exports" ], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self,
factory(global["cryptpad-worker"] = {}));
})(this, (function(exports) {
"use strict";
function _mergeNamespaces(n, m) {
m.forEach((function(e) {
e && typeof e !== "string" && !Array.isArray(e) && Object.keys(e).forEach((function(k) {
if (k !== "default" && !(k in n)) {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function() {
return e[k];
}
});
}
}));
}));
return Object.freeze(n);
}
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
function getDefaultExportFromCjs(x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
}
function getAugmentedNamespace(n) {
if (n.__esModule) return n;
var f = n.default;
if (typeof f == "function") {
var a = function a() {
if (this instanceof a) {
return Reflect.construct(f, arguments, this.constructor);
}
return f.apply(this, arguments);
};
a.prototype = f.prototype;
} else a = {};
Object.defineProperty(a, "__esModule", {
value: true
});
Object.keys(n).forEach((function(k) {
var d = Object.getOwnPropertyDescriptor(n, k);
Object.defineProperty(a, k, d.get ? d : {
enumerable: true,
get: function() {
return n[k];
}
});
}));
return a;
}
var chainpadListmap = {
exports: {}
};
var chainpadNetflux = {
exports: {}
};
var netfluxClient = {
exports: {}
};
var hasRequiredNetfluxClient;
function requireNetfluxClient() {
if (hasRequiredNetfluxClient) return netfluxClient.exports;
hasRequiredNetfluxClient = 1;
(function(module) {
(function() {
var factory = function() {
var MAX_LAG_BEFORE_PING = 15e3;
var MAX_LAG_BEFORE_DISCONNECT = 6e4;
var PING_CYCLE = 5e3;
var REQUEST_TIMEOUT = 3e4;
var FORCE_CLOSE_TIMEOUT = 1e4;
var RECONNECT_LOOP_CYCLE = 7e3;
var NOFUNC = function() {};
var now = function now() {
return (new Date).getTime();
};
var getLag = function(ctx) {
if (!ctx.ws) {
return null;
}
if (!ctx.pingOutstanding) {
return ctx.lastObservedLag;
}
return Math.max(now() - ctx.timeOfLastPingSent, ctx.lastObservedLag);
};
var setTimeoutX = function(ctx, func, time) {
ctx.timeouts.push(setTimeout(func, time));
};
var closeWebsocket = function(ctx, offline) {
if (!ctx.ws) {
return;
}
ctx.ws.onmessage = NOFUNC;
ctx.ws.onopen = NOFUNC;
ctx.ws.close();
if (offline) {
ctx.ws.onclose({
reason: "offline"
});
return;
}
setTimeoutX(ctx, (function() {
if (!ctx.ws) {
return;
}
ctx.ws.onclose({
reason: "forced closed because websocket failed to close"
});
}), FORCE_CLOSE_TIMEOUT);
};
var send = function(ctx, content) {
if (!ctx.ws) {
return false;
}
ctx.ws.send(JSON.stringify(content));
return true;
};
var networkSendTo = function networkSendTo(ctx, peerId, content) {
var seq = ctx.seq++;
var message = [ seq, "MSG", peerId, content ];
var sent = send(ctx, message);
return new Promise((function(res, rej) {
if (!sent) {
return void rej({
type: "DISCONNECTED",
message: JSON.stringify(message)
});
}
ctx.requests[seq] = {
reject: rej,
resolve: res,
time: now()
};
}));
};
var channelBcast = function channelBcast(ctx, chanId, content) {
var chan = ctx.channels[chanId];
var seq = ctx.seq++;
var message = [ seq, "MSG", chanId, content ];
if (!chan) {
return new Promise((function(res, rej) {
rej({
type: "NO_SUCH_CHANNEL",
message: JSON.stringify(message)
});
}));
}
var sent = send(ctx, message);
return new Promise((function(res, rej) {
if (!sent) {
return void rej({
type: "DISCONNECTED",
message: JSON.stringify(message)
});
}
ctx.requests[seq] = {
reject: rej,
resolve: res,
time: now()
};
}));
};
var channelLeave = function channelLeave(ctx, chanId, reason) {
var chan = ctx.channels[chanId];
if (!chan) {
return void console.debug("no such channel", chanId);
}
delete ctx.channels[chanId];
if (!ctx.ws || ctx.ws.readyState !== 1) {
return;
}
var seq = ctx.seq++;
send(ctx, [ seq, "LEAVE", chanId, reason ]);
var emptyFunction = function() {};
ctx.requests[seq] = {
reject: emptyFunction,
resolve: emptyFunction,
time: now()
};
};
var makeEventHandlers = function makeEventHandlers(ctx, mappings) {
return function(name, handler) {
var handlers = mappings[name];
if (!handlers) {
throw new Error("no such event " + name);
}
handlers.push(handler);
};
};
var removeEventHandler = function(ctx, name, handler, mappings) {
var handlers = mappings[name];
if (!handlers) {
throw new Error("no such event " + name);
}
var idx = handlers.indexOf(handler);
if (idx === -1) {
return;
}
handlers.splice(idx, 1);
};
var mkChannel = function mkChannel(ctx, id, priority) {
if (ctx.channels[id]) {
return new Promise((function(res) {
res(ctx.channels[id]);
}));
}
var q = ctx.queues.p2;
if (priority === 1) {
q = ctx.queues.p1;
} else if (priority === 3) {
q = ctx.queues.p3;
}
var internal = {
queue: q,
onMessage: [],
onJoin: [],
onLeave: [],
members: [],
jSeq: ctx.seq++
};
var mappings = {
message: internal.onMessage,
join: internal.onJoin,
leave: internal.onLeave
};
var chan = {
_: internal,
time: now(),
id,
members: internal.members,
bcast: function bcast(msg) {
return channelBcast(ctx, chan.id, msg);
},
leave: function leave(reason) {
return channelLeave(ctx, chan.id, reason);
},
on: makeEventHandlers(ctx, mappings),
off: function(name, handler) {
removeEventHandler(ctx, name, handler, mappings);
}
};
ctx.requests[internal.jSeq] = chan;
var message = [ internal.jSeq, "JOIN", id ];
var sent = send(ctx, message);
return new Promise((function(res, rej) {
if (!sent) {
return void rej({
type: "DISCONNECTED",
message: JSON.stringify(message)
});
}
chan._.resolve = res;
chan._.reject = rej;
}));
};
var disconnect = function(ctx) {
if (ctx.ws) {
var onclose = ctx.ws.onclose;
ctx.ws.onclose = NOFUNC;
ctx.ws.close();
onclose({
reason: "network.disconnect() called"
});
}
ctx.timeouts.forEach(clearTimeout);
ctx.timeouts = [];
};
var mkNetwork = function mkNetwork(ctx) {
var mappings = {
message: ctx.onMessage,
disconnect: ctx.onDisconnect,
reconnect: ctx.onReconnect
};
var network = {
webChannels: ctx.channels,
getLag: function _getLag() {
return getLag(ctx);
},
sendto: function sendto(peerId, content) {
return networkSendTo(ctx, peerId, content);
},
join: function join(chanId, priority) {
return mkChannel(ctx, chanId, priority);
},
disconnect: function() {
return disconnect(ctx);
},
on: makeEventHandlers(ctx, mappings),
off: function(name, handler) {
removeEventHandler(ctx, name, handler, mappings);
}
};
network.__defineGetter__("webChannels", (function() {
return Object.keys(ctx.channels).map((function(k) {
return ctx.channels[k];
}));
}));
return network;
};
var process = function(ctx) {
if (ctx.queues.busy) {
return;
}
var next = function() {
var obj = ctx.queues.p1.shift() || ctx.queues.p2.shift() || ctx.queues.p3.shift();
if (!obj) {
ctx.queues.busy = false;
return;
}
ctx.queues.busy = true;
var handlers = obj.h;
var msg = obj.msg;
handlers.forEach((function(h) {
setTimeout((function() {
try {
h(msg[4], msg[1]);
} catch (e) {
console.error(e);
}
}));
}));
setTimeout((function() {
next();
}));
};
next();
};
var onMessage = function onMessage(ctx, evt) {
var msg = void 0;
try {
msg = JSON.parse(evt.data);
} catch (e) {
console.log(e.stack);
return;
}
ctx.timeOfLastMsgReceived = now();
if (msg[0] !== 0) {
var req = ctx.requests[msg[0]];
if (!req) {
console.log("error: " + JSON.stringify(msg));
return;
}
delete ctx.requests[msg[0]];
if (msg[1] === "ACK") {
if (req.ping) {
ctx.lastObservedLag = now() - Number(req.ping);
ctx.timeOfLastPingReceived = now();
ctx.pingOutstanding--;
return;
}
req.resolve();
} else if (msg[1] === "JACK") {
if (req._) {
if (!msg[2]) {
throw new Error("wrong type of ACK for channel join");
}
req.id = msg[2];
ctx.channels[req.id] = req;
return;
}
req.resolve();
} else if (msg[1] === "ERROR") {
if (typeof req.reject === "function") {
req.reject({
type: msg[2],
message: msg[3]
});
} else if (req._ && typeof req._.reject === "function") {
if (msg[2] === "EJOINED" && !ctx.channels[msg[3]]) {
req.id = msg[3];
ctx.channels[req.id] = req;
return;
}
req._.reject({
type: msg[2],
message: msg[3]
});
} else {
console.error(msg);
}
} else {
req.reject({
type: "UNKNOWN",
message: JSON.stringify(msg)
});
}
return;
}
if (msg[2] === "IDENT") {
ctx.uid = msg[3];
ctx.ws._onident();
ctx.pingInterval = setInterval((function() {
if (now() - ctx.timeOfLastPingReceived < MAX_LAG_BEFORE_PING) {
return;
}
if (now() - ctx.timeOfLastMsgReceived > MAX_LAG_BEFORE_DISCONNECT) {
closeWebsocket(ctx);
}
if (ctx.pingOutstanding) {
return;
}
var seq = ctx.seq++;
var currentDate = now();
ctx.timeOfLastPingSent = currentDate;
ctx.pingOutstanding++;
ctx.requests[seq] = {
time: currentDate,
ping: currentDate
};
send(ctx, [ seq, "PING" ]);
}), PING_CYCLE);
return;
} else if (!ctx.uid) {
return;
}
if (msg[2] === "PING") {
msg[2] = "PONG";
send(ctx, msg);
return;
}
if (msg[2] === "MSG") {
var handlers = void 0;
var q = ctx.queues.p2;
if (msg[3] === ctx.uid) {
handlers = ctx.onMessage;
if (typeof msg[5] === "number") {
if (msg[5] === 1) {
q = ctx.queues.p1;
}
if (msg[5] === 3) {
q = ctx.queues.p3;
}
}
} else {
var chan = ctx.channels[msg[3]];
if (!chan) {
console.log("message to non-existent chan " + JSON.stringify(msg));
return;
}
handlers = chan._.onMessage;
if (chan._.queue) {
q = chan._.queue;
}
}
q.push({
msg,
h: handlers
});
process(ctx);
}
if (msg[2] === "LEAVE") {
var _chan = ctx.channels[msg[3]];
if (!_chan) {
if (msg[1] !== ctx.uid) {
console.log("leaving non-existent chan " + JSON.stringify(msg));
}
return;
}
var leaveIdx = _chan._.members.indexOf(msg[1]);
if (leaveIdx !== -1) {
_chan._.members.splice(leaveIdx, 1);
}
_chan._.onLeave.forEach((function(h) {
try {
h(msg[1], msg[4]);
} catch (e) {
console.log(e.stack);
}
}));
}
if (msg[2] === "JOIN") {
var _chan2 = ctx.channels[msg[3]];
if (!_chan2) {
console.log("ERROR: join to non-existent chan " + JSON.stringify(msg));
return;
}
if (_chan2._.members.indexOf(msg[1]) !== -1) {
return;
}
var synced = _chan2._.members.indexOf(ctx.uid) !== -1;
_chan2._.members.push(msg[1]);
if (!synced && msg[1] === ctx.uid) {
_chan2.myID = ctx.uid;
_chan2._.resolve(_chan2);
}
if (synced) {
_chan2._.onJoin.forEach((function(h) {
try {
h(msg[1]);
} catch (e) {
console.log(e.stack);
}
}));
}
}
};
var connect = function connect(websocketURL, makeWebsocket) {
makeWebsocket = makeWebsocket || function(url) {
return new window.WebSocket(url);
};
var ctx = {
ws: null,
seq: 1,
uid: null,
network: null,
channels: {},
onMessage: [],
onDisconnect: [],
onReconnect: [],
timeouts: [],
requests: {},
pingInterval: null,
queues: {
p1: [],
p2: [],
p3: []
},
timeOfLastPingSent: -1,
timeOfLastPingReceived: -1,
timeOfLastMsgReceived: -1,
lastObservedLag: 0,
pingOutstanding: 0
};
ctx.network = mkNetwork(ctx);
var promiseResolve = NOFUNC;
var promiseReject = NOFUNC;
if (typeof window !== "undefined") {
window.addEventListener("offline", (function() {
if ([ "localhost", "127.0.0.1", "" ].indexOf(window.location.hostname) !== -1) {
return;
}
closeWebsocket(ctx, true);
}));
}
var connectWs = function() {
var ws = ctx.ws = makeWebsocket(websocketURL);
ctx.timeOfLastPingSent = ctx.timeOfLastPingReceived = now();
ctx.timeOfLastMsgReceived = now();
ws.onmessage = function(msg) {
return onMessage(ctx, msg);
};
ws.onclose = function(evt) {
ws.onclose = NOFUNC;
clearInterval(ctx.pingInterval);
ctx.timeouts.forEach(clearTimeout);
ctx.ws = null;
if (ctx.uid) {
ctx.uid = null;
ctx.onDisconnect.forEach((function(h) {
try {
h(evt.reason);
} catch (e) {
console.log(e.stack);
}
}));
}
setTimeoutX(ctx, connectWs, ctx.uid ? 0 : RECONNECT_LOOP_CYCLE);
};
ws.onopen = function() {
setTimeoutX(ctx, (function() {
if (ctx.uid) {
return;
}
promiseReject({
type: "TIMEOUT",
message: "waited " + REQUEST_TIMEOUT + "ms"
});
promiseResolve = promiseReject = NOFUNC;
closeWebsocket(ctx);
}), REQUEST_TIMEOUT);
};
ctx.ws._onident = function() {
ctx.timeOfLastPingReceived = now();
ctx.timeOfLastMsgReceived = now();
ctx.lastObservedLag = now() - ctx.timeOfLastPingSent;
if (promiseResolve !== NOFUNC) {
promiseResolve(ctx.network);
promiseResolve = promiseReject = NOFUNC;
} else {
ctx.channels = {};
ctx.requests = {};
ctx.pingOutstanding = 0;
ctx.onReconnect.forEach((function(h) {
try {
h(ctx.uid);
} catch (e) {
console.log(e.stack);
}
}));
}
};
};
return new Promise((function(resolve, reject) {
promiseResolve = resolve;
promiseReject = reject;
connectWs();
}));
};
return {
connect
};
};
if (module.exports) {
module.exports = factory();
} else {
window.netflux_websocket = factory();
}
})();
})(netfluxClient);
return netfluxClient.exports;
}
var hasRequiredChainpadNetflux;
function requireChainpadNetflux() {
if (hasRequiredChainpadNetflux) return chainpadNetflux.exports;
hasRequiredChainpadNetflux = 1;
(function(module) {
(function() {
var factory = function(Netflux) {
var USE_HISTORY = true;
var CPNF = {};
var verbose = function(x) {
console.log(x);
};
verbose = function() {};
var unBencode = function(str) {
return str.replace(/^\d+:/, "");
};
var removeCp = CPNF.removeCp = function(str) {
return str.replace(/^cp\|([A-Za-z0-9+\/=]{0,20}\|)?/, "");
};
CPNF.start = function(config) {
config = config || {};
var network = config.network;
var websocketUrl = config.websocketURL;
var userName = config.userName;
var channel = config.channel;
var Crypto = config.crypto;
var readOnly = config.readOnly || false;
var ChainPad = !config.noChainPad && (config.ChainPad || window.ChainPad);
var useHistory = typeof config.useHistory === "undefined" ? USE_HISTORY : !!config.useHistory;
var stopped = false;
var lastKnownHash = config.lastKnownHash;
var lastSent = {};
var messagesQueue = [];
var priority = config.priority || 2;
var Cache = config.Cache;
var channelCache;
var initialCache = false;
var txid = Math.floor(Math.random() * 1e6);
var metadata = config.metadata || {};
var validateKey = metadata.validateKey = config.validateKey || metadata.validateKey;
metadata.owners = config.owners || metadata.owners;
metadata.expire = config.expire || metadata.expire;
var initializing = true;
var toReturn = {
setReadOnly: function(state, crypto) {
readOnly = state;
if (crypto) {
Crypto = crypto;
}
}
};
var joinSession = function() {};
var realtime;
var lastKnownHistoryKeeper;
var historyKeeperChange = [];
var wcObject = {
send: function() {}
};
var createRealtime = function() {
if (realtime && typeof realtime.abort === "function") {
realtime.abort();
}
var chainpad = ChainPad.create({
userName,
initialState: config.initialState,
transformFunction: config.transformFunction,
patchTransformer: config.patchTransformer,
validateContent: config.validateContent,
avgSyncMilliseconds: config.avgSyncMilliseconds,
logLevel: typeof config.logLevel !== "undefined" ? config.logLevel : 1
});
if (Cache && Array.isArray(channelCache) && channelCache.length) {
channelCache.forEach((function(obj) {
var patch = obj.patch;
if (!/^\[/.test(patch)) {
try {
patch = Crypto.decrypt(patch, validateKey, true);
} catch (err) {
console.error(patch, validateKey, channel);
console.error(err);
}
patch = unBencode(patch);
}
chainpad.message(patch);
}));
var doc = chainpad.getUserDoc();
if (doc === "") {
chainpad.abort();
channelCache = [];
Cache.clearChannel(channel);
return createRealtime();
}
}
chainpad.onMessage((function(msg, cb, curve) {
wcObject.send(msg, cb, curve);
}));
chainpad.onPatch((function(patch) {
if (config.onRemote) {
config.onRemote({
realtime: chainpad,
patch
});
}
}));
return chainpad;
};
var userList = {
change: [],
onChange: function(newData) {
userList.change.forEach((function(el) {
el(newData);
}));
},
users: []
};
var onJoining = function(peer) {
if (config.onJoin) {
config.onJoin(peer);
}
if (peer.length !== 32) {
return;
}
var list = userList.users;
var index = list.indexOf(peer);
if (index === -1) {
userList.users.push(peer);
}
userList.onChange();
};
var connectTo = function() {};
var onLeaving = function(peer) {
if (config.onLeave) {
config.onLeave(peer);
}
var list = userList.users;
var index = list.indexOf(peer);
if (index !== -1) {
userList.users.splice(index, 1);
}
userList.onChange();
};
var onReady = function(wc, network) {
if (!initializing) {
return;
}
try {
var doc = realtime && realtime.getUserDoc();
if (initialCache && realtime && (doc === "" || doc === config.initialState)) {
return void toReturn.resetCache();
}
} catch (e) {
console.error(e);
}
if (realtime) {
realtime.start();
}
if (config.setMyID) {
config.setMyID({
myID: wc.myID
});
}
initializing = false;
if (config.onReady) {
config.onReady({
realtime,
network,
userList,
myId: wc.myID,
leave: wc.leave,
metadata
});
}
if (messagesQueue.length) {
messagesQueue.forEach((function(f) {
if (typeof f !== "function") {
return;
}
f();
}));
messagesQueue = [];
}
};
var onChannelError = function(parsed, wc) {
if (config.onChannelError) {
config.onChannelError({
channel: wc.id,
type: parsed.error,
loaded: !initializing,
error: parsed.error,
message: parsed.message
});
}
if (parsed.error === "EUNKNOWN") {
lastKnownHash = undefined;
if (wc) {
wc.leave();
}
if (Cache) {
channelCache = [];
Cache.clearChannel(channel, (function() {
if (ChainPad) {
toReturn.realtime = realtime = createRealtime();
}
joinSession(network, connectTo);
}));
return;
}
joinSession(network, connectTo);
return;
}
if (typeof toReturn.stop === "function") {
try {
toReturn.stop();
} catch (e) {}
}
};
var firstFillCache = true;
var fillCache = function(obj) {
if (!Cache) {
return;
}
if (channelCache.length && channelCache[channelCache.length - 1].hash === obj.hash) {
return;
}
if (!channelCache.length && firstFillCache) {
obj.isCheckpoint = true;
firstFillCache = false;
}
if (!channelCache.length && !obj.isCheckpoint) {
return;
}
channelCache.push(obj);
Cache.storeCache(channel, validateKey, channelCache, (function(err) {
if (err) {
Cache.clearChannel(channel, (function() {
console.warn("Cache cleared", channel);
}));
var _cache = channelCache;
channelCache = [];
return void console.error(err, channel, _cache, validateKey);
}
}));
};
var onMessage = function(peer, msg, wc, network, direct) {
var hk = network.historyKeeper;
var isHk = peer === hk;
if (wc && (msg === 0 || msg === "0")) {
return void onReady(wc, network);
}
if (direct && peer !== hk) {
return;
}
if (direct) {
var parsed = JSON.parse(msg);
if (parsed.txid && parsed.txid !== txid) {
return;
}
if (parsed.validateKey && parsed.channel) {
if (parsed.channel === wc.id && !validateKey) {
validateKey = parsed.validateKey;
}
if (parsed.channel === wc.id) {
metadata = parsed;
if (config.onMetadataUpdate && !initializing) {
config.onMetadataUpdate(metadata);
}
}
return;
}
if (parsed.state && parsed.state === 1 && parsed.channel) {
if (parsed.channel === wc.id) {
Object.keys(lastSent).forEach((function(h) {
if (typeof lastSent[h] === "function") {
lastSent[h]("FAILED");
}
}));
lastSent = {};
onReady(wc, network);
}
return;
}
}
if (isHk) {
var parsed1 = JSON.parse(msg);
if (Array.isArray(parsed1) && parsed1[0] && parsed1[0] !== txid) {
return;
}
if (parsed1.channel === wc.id && parsed1.error) {
onChannelError(parsed1, wc);
return;
}
msg = parsed1[4];
if (parsed1[3] !== wc.id) {
return;
}
}
lastKnownHash = msg.slice(0, 64);
if (typeof lastSent[lastKnownHash] === "function") {
lastSent[lastKnownHash](null, lastKnownHash);
delete lastSent[lastKnownHash];
return;
}
var isCp = /^cp\|/.test(msg);
msg = removeCp(msg);
try {
msg = Crypto.decrypt(msg, validateKey, isHk);
} catch (err) {
console.error(msg, validateKey, channel);
console.error(err);
}
var senderCurve;
var isString = typeof msg === "string";
if (!isString && msg.content) {
senderCurve = msg.author;
msg = msg.content;
}
verbose(msg);
if (!initializing) {
if (config.onLocal) {
config.onLocal(true);
}
}
var message = isString ? unBencode(msg) : msg;
var apply = function() {
try {
if (realtime && isString) {
realtime.message(message);
}
if (config.onMessage) {
var obj = {
time: parsed1 ? parsed1[5] : +new Date
};
config.onMessage(message, peer, validateKey, isCp, lastKnownHash, senderCurve, obj);
}
var isCacheCp = isCp;
if (config.isCacheCheckpoint) {
isCacheCp = config.isCacheCheckpoint(message, senderCurve);
}
fillCache({
patch: message,
hash: lastKnownHash,
isCheckpoint: isCacheCp,
author: senderCurve,
time: parsed1 ? parsed1[5] : +new Date
});
} catch (e) {
console.error(e);
}
};
if (initializing && peer !== hk) {
messagesQueue.push(apply);
return;
}
apply();
};
var msgOut = function(msg, curvePublic) {
if (readOnly) {
return;
}
try {
var cmsg = Crypto.encrypt(msg, curvePublic);
if (msg.indexOf("[4") === 0) {
var id = "";
if (window.nacl) {
var hash = window.nacl.hash(window.nacl.util.decodeUTF8(msg));
id = window.nacl.util.encodeBase64(hash.slice(0, 8)) + "|";
} else {
console.log("Checkpoint sent without an ID. Nacl is missing.");
}
cmsg = "cp|" + id + cmsg;
}
return cmsg;
} catch (err) {
console.log(msg);
throw err;
}
};
var onOpen = function(wc, network, firstConnection) {
wcObject.wc = wc;
channel = wc.id;
wc.members.forEach(onJoining);
var onMessageHandler = function(msg, sender) {
onMessage(sender, msg, wc, network);
};
wc.on("message", onMessageHandler);
wc.on("join", onJoining);
wc.on("leave", onLeaving);
wcObject.stop = function() {
wc.off("message", onMessageHandler);
wc.off("join", onJoining);
wc.off("leave", onLeaving);
wc.leave();
if (realtime) {
realtime.abort();
}
};
if (firstConnection) {
wcObject.send = function(_message, cb, curvePublic) {
var message = msgOut(_message, curvePublic);
if (message) {
var hash = message.slice(0, 64);
var isCacheCp = /^cp\|/.test(message);
if (config.isCacheCheckpoint) {
isCacheCp = config.isCacheCheckpoint(_message, curvePublic);
}
lastSent[hash] = function(err, _hash) {
if (!err && _hash) {
fillCache({
patch: removeCp(_message),
hash,
isCheckpoint: isCacheCp,
author: curvePublic,
time: +new Date
});
}
cb(err, _hash);
};
wcObject.wc.bcast(message).then((function() {
lastKnownHash = hash;
delete lastSent[hash];
fillCache({
patch: removeCp(_message),
hash,
isCheckpoint: isCacheCp,
author: curvePublic,
time: +new Date
});
cb(null, hash);
}), (function(err) {
console.error(err);
if (err && (err.type === "enoent" || err.type === "ENOENT")) {
wcObject.wc.leave();
if (stopped) {
delete lastSent[hash];
return void cb("STOPPED");
}
initializing = true;
network.join(channel, priority).then((function(wc) {
onOpen(wc, network, false);
wcObject.send(_message, cb, curvePublic);
}));
} else {
delete lastSent[hash];
cb(err && err.type || err);
}
}));
}
};
if (ChainPad && !realtime) {
toReturn.realtime = realtime = createRealtime();
}
if (config.onInit) {
config.onInit({
myID: wc.myID,
realtime,
getLag: network.getLag,
userList,
network,
channel
});
}
}
if (config.onConnect) {
config.onConnect(wc, wcObject.send);
}
if (useHistory) {
var hk;
wc.members.forEach((function(p) {
if (p.length === 16) {
hk = p;
}
}));
if (lastKnownHistoryKeeper !== hk) {
network.historyKeeper = hk;
lastKnownHistoryKeeper = hk;
historyKeeperChange.forEach((function(f) {
f(hk);
}));
}
var sendGetHistory = function() {
var cfg = {
txid,
priority,
lastKnownHash,
metadata
};
if (Cache && Array.isArray(channelCache) && channelCache.length) {
cfg.lastKnownHash = channelCache[channelCache.length - 1].hash;
}
messagesQueue = [];
var msg = [ "GET_HISTORY", wc.id, cfg ];
if (hk) {
network.sendto(hk, JSON.stringify(msg));
}
};
sendGetHistory();
toReturn.resetCache = function() {
initializing = true;
channelCache = [];
if (Cache) {
Cache.clearChannel(channel);
}
txid = Math.floor(Math.random() * 1e6);
onChannelError({
error: "EUNKNOWN",
message: "Corrupted cache"
}, wc);
};
} else {
onReady(wc, network);
}
};
var isIntentionallyLeaving = false;
if (typeof window !== "undefined") {
window.addEventListener("beforeunload", (function() {
isIntentionallyLeaving = true;
}));
}
var findChannelById = function(webChannels, channelId) {
var webChannel;
webChannels.some((function(chan) {
if (chan.id === channelId) {
webChannel = chan;
return true;
}
}));
return webChannel;
};
var onConnectError = function(err) {
if (config.onError) {
config.onError({
type: err.type || err,
message: err.message,
error: err.type,
loaded: !initializing
});
}
};
joinSession = function(endPoint, cb) {
var promise;
if (typeof endPoint === "string") {
promise = Netflux.connect(endPoint);
}
var join = function() {
if (typeof endPoint === "string") {
promise.then(cb, onConnectError);
} else if (typeof endPoint.then === "function") {
endPoint.then(cb, onConnectError);
} else {
cb(endPoint);
}
};
if (Cache) {
Cache.getChannelCache(channel, (function(err, cache) {
validateKey = cache ? cache.k : undefined;
channelCache = cache ? cache.c : [];
if (!channelCache.length) {
return void join();
}
initialCache = true;
if (config.onCacheStart) {
config.onCacheStart();
}
if (ChainPad) {
toReturn.realtime = realtime = createRealtime();
}
if (!channelCache.length) {
return void join();
}
if (config.onMessage) {
channelCache.forEach((function(obj) {
var _obj = {
time: obj.time
};
config.onMessage(obj.patch, "cache", validateKey, obj.isCheckpoint, obj.hash, obj.author, _obj);
}));
}
if (config.onCacheReady) {
config.onCacheReady({
id: channel,
realtime,
networkPromise: promise
});
}
join();
}));
toReturn.resetCache = function() {
if (Cache) {
Cache.clearChannel(channel);
}
channelCache = [];
};
return;
}
join();
};
var firstConnection = true;
connectTo = function(network, first) {
if (stopped) {
return;
}
network.join(channel || null, priority).then((function(wc) {
if (stopped) {
try {
wc.leave();
} catch (e) {}
return;
}
onOpen(wc, network, first);
}), (function(error) {
if (error && error.type === "ERESTRICTED" && Array.isArray(error.message)) {
if (config.onRejected) {
return void config.onRejected(error.message, (function(err) {
if (err) {
return void onConnectError(error);
}
connectTo(network, first);
}));
}
}
onConnectError(error);
}));
};
toReturn.stop = function() {
stopped = true;
};
joinSession(network || websocketUrl, (function(_network) {
network = _network;
if (firstConnection) {
firstConnection = false;
if (stopped) {
return;
}
var onDisconnectHandler = function(reason) {
if (isIntentionallyLeaving) {
return;
}
if (reason === "network.disconnect() called") {
return;
}
if (config.onConnectionChange) {
config.onConnectionChange({
state: false
});
return;
}
if (config.onAbort) {
config.onAbort({
reason
});
}
};
var onReconnectHandler = function(uid) {
if (config.onConnectionChange) {
config.onConnectionChange({
state: true,
myId: uid
});
var afterReconnecting = function() {
initializing = true;
userList.users = [];
joinSession(network, connectTo);
};
if (config.beforeReconnecting) {
config.beforeReconnecting((function(newKey, newContent) {
channel = newKey;
config.initialState = newContent;
afterReconnecting();
}));
return;
}
afterReconnecting();
}
};
var onMessageHandler = function(msg, sender) {
var wchan = findChannelById(network.webChannels, channel);
if (wchan) {
onMessage(sender, msg, wchan, network, true);
}
};
network.on("disconnect", onDisconnectHandler);
network.on("reconnect", onReconnectHandler);
network.on("message", onMessageHandler);
toReturn.network = network;
toReturn.stop = function() {
if (wcObject && wcObject.stop) {
wcObject.stop();
}
var wchan = findChannelById(network.webChannels, channel);
if (wchan) {
try {
wchan.leave("");
} catch (e) {}
}
network.off("disconnect", onDisconnectHandler);
network.off("reconnect", onReconnectHandler);
network.off("message", onMessageHandler);
stopped = true;
};
network.onHistoryKeeperChange = function(todo) {
historyKeeperChange.push(todo);
};
}
connectTo(network, true);
}));
return toReturn;
};
return CPNF;
};
if (module.exports) {
module.exports = factory(requireNetfluxClient());
}
})();
})(chainpadNetflux);
return chainpadNetflux.exports;
}
/*!
* Copyright 2015-2016 Thomas Rosenau
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ var lib;
var hasRequiredLib;
function requireLib() {
if (hasRequiredLib) return lib;
hasRequiredLib = 1;
const sortKeys = o => {
if (Array.isArray(o)) {
return o.map(sortKeys);
} else if (o instanceof Object) {
let numeric = [];
let nonNumeric = [];
Object.keys(o).forEach((key => {
if (/^(0|[1-9][0-9]*)$/.test(key)) {
numeric.push(+key);
} else {
nonNumeric.push(key);
}
}));
return numeric.sort((function(a, b) {
return a - b;
})).concat(nonNumeric.sort()).reduce(((result, key) => {
result[key] = sortKeys(o[key]);
return result;
}), {});
}
return o;
};
const jsonStringify = JSON.stringify.bind(JSON);
const sortify = (value, replacer, space) => {
let native = jsonStringify(value, replacer, 0);
if (!native || native[0] !== "{" && native[0] !== "[") {
return native;
}
let cleanObj = JSON.parse(native);
return jsonStringify(sortKeys(cleanObj), null, space);
};
lib = sortify;
return lib;
}
var json_sortify;
var hasRequiredJson_sortify;
function requireJson_sortify() {
if (hasRequiredJson_sortify) return json_sortify;
hasRequiredJson_sortify = 1;
json_sortify = requireLib();
return json_sortify;
}
var hasRequiredChainpadListmap;
function requireChainpadListmap() {
if (hasRequiredChainpadListmap) return chainpadListmap.exports;
hasRequiredChainpadListmap = 1;
(function(module) {
(function() {
var factory = function(Realtime, Sortify) {
const window = globalThis;
var api = {};
var ChainPad;
var isFakeProxy = typeof window.Proxy === "undefined";
var DeepProxy = api.DeepProxy = function() {
var deepProxy = {};
var isArray = deepProxy.isArray = Array.isArray || function(obj) {
return Object.toString(obj) === "[object Array]";
};
var type = deepProxy.type = function(dat) {
return dat === null ? "null" : isArray(dat) ? "array" : typeof dat;
};
var isProxyable = deepProxy.isProxyable = function(obj, forceCheck) {
if (typeof forceCheck === "undefined" && isFakeProxy) {
return false;
}
return [ "object", "array" ].indexOf(type(obj)) !== -1;
};
var setter = deepProxy.set = function(cb) {
return function(obj, prop, value) {
if (prop === "on") {
throw new Error("'on' is a reserved attribute name for realtime lists and maps");
}
if (isProxyable(value)) {
obj[prop] = deepProxy.create(value, cb);
} else {
obj[prop] = value;
}
cb();
return obj[prop] || true;
};
};
var pathMatches = deepProxy.pathMatches = function(path, pattern) {
return !pattern.some((function(x, i) {
return x !== path[i];
}));
};
var lengthDescending = function(a, b) {
return b.pattern.length - a.pattern.length;
};
var on = function(events) {
return function(evt, pattern, f) {
switch (evt) {
case "change":
pattern = type(pattern) === "array" ? pattern : [ pattern ];
events.change.push({
cb: function(oldval, newval, path, root) {
if (pathMatches(path, pattern)) {
return f(oldval, newval, path, root);
}
},
pattern
});
events.change.sort(lengthDescending);
break;
case "remove":
pattern = type(pattern) === "array" ? pattern : [ pattern ];
events.remove.push({
cb: function(oldval, path, root) {
if (pathMatches(path, pattern)) {
return f(oldval, path, root);
}
},
pattern
});
events.remove.sort(lengthDescending);
break;
case "ready":
events.ready.push({
cb: function(info) {
pattern(info);
}
});
break;
case "cacheready":
events.cacheready.push({
cb: function(info) {
pattern(info);
}
});
break;
case "disconnect":
events.disconnect.push({
cb: function(info) {
pattern(info);
}
});
break;
case "reconnect":
events.reconnect.push({
cb: function(info) {
pattern(info);
}
});
break;
case "create":
events.create.push({
cb: function(info) {
pattern(info);
}
});
break;
case "error":
events.error.push({
cb: function(info) {
pattern(info);
}
});
break;
}
return this;
};
};
var getter = deepProxy.get = function() {
var events = {
cacheready: [],
disconnect: [],
reconnect: [],
change: [],
ready: [],
remove: [],
create: [],
error: []
};
return function(obj, prop) {
if (prop === "on") {
return on(events);
} else if (prop === "_isProxy") {
return true;
} else if (prop === "_events") {
return events;
}
return obj[prop];
};
};
var deleter = deepProxy.delete = function(cb) {
return function(obj, prop) {
if (typeof obj[prop] === "undefined") {
return true;
}
delete obj[prop];
cb();
return true;
};
};
var handlers = deepProxy.handlers = function(cb, isRoot) {
if (!isRoot) {
return {
set: setter(cb),
get: function(obj, prop) {
if (prop === "_isProxy") {
return true;
}
return obj[prop];
},
deleteProperty: deleter(cb)
};
}
return {
set: setter(cb),
get: getter(cb),
deleteProperty: deleter(cb)
};
};
var remoteChangeFlag = deepProxy.remoteChangeFlag = false;
var stringifyFakeProxy = deepProxy.stringifyFakeProxy = function(proxy) {
var copy = JSON.parse(Sortify(proxy));
delete copy._events;
delete copy._isProxy;
return Sortify(copy);
};
deepProxy.checkLocalChange = function(obj, cb) {
if (!isFakeProxy) {
return;
}
if (deepProxy.interval) {
return;
}
var oldObj = stringifyFakeProxy(obj);
deepProxy.interval = window.setInterval((function() {
var newObj = stringifyFakeProxy(obj);
if (newObj !== oldObj) {
oldObj = newObj;
if (remoteChangeFlag) {
remoteChangeFlag = false;
} else {
cb();
}
}
}), 300);
};
var create = deepProxy.create = function(obj, opt, isRoot) {
var methods = type(opt) === "function" ? handlers(opt, isRoot) : opt;
switch (type(obj)) {
case "object":
var keys = Object.keys(obj);
keys.forEach((function(k) {
if (isProxyable(obj[k]) && !obj[k]._isProxy) {
obj[k] = create(obj[k], opt);
}
}));
break;
case "array":
obj.forEach((function(o, i) {
if (isProxyable(o) && !o._isProxy) {
obj[i] = create(obj[i], opt);
}
}));
break;
default:
throw new Error("attempted to make a proxy of an unproxyable object");
}
if (!isFakeProxy) {
if (obj._isProxy) {
return obj;
}
return new window.Proxy(obj, methods);
}
var proxy = JSON.parse(JSON.stringify(obj));
if (isRoot) {
var events = {
cacheready: [],
disconnect: [],
reconnect: [],
change: [],
ready: [],
remove: [],
create: [],
error: []
};
proxy.on = on(events);
proxy._events = events;
}
return proxy;
};
var onChange = function(path, key, root, oldval, newval) {
var P = path.slice(0);
P.push(key);
root._events.change.some((function(handler) {
return handler.cb(oldval, newval, P, root) === false;
}));
};
var find = deepProxy.find = function(map, path) {
var l = path.length;
for (var i = 0; i < l; i++) {
if (typeof map[path[i]] === "undefined") {
return;
}
map = map[path[i]];
}
return map;
};
var onRemove = function(path, key, root, old, top) {
var newpath = path.concat(key);
var X = find(root, newpath);
var t_X = type(X);
switch (t_X) {
case "array":
if (top) {
onChange(path, key, root, old, undefined);
} else {
root._events.remove.forEach((function(handler) {
return handler.cb(X, newpath, root);
}));
}
X.forEach((function(x, i) {
onRemove(newpath, i, root);
}));
break;
case "object":
if (top) {
onChange(path, key, root, old, undefined);
} else {
root._events.remove.forEach((function(handler) {
return handler.cb(X, newpath, root, old, false);
}));
}
Object.keys(X).forEach((function(key) {
onRemove(newpath, key, root, X[key], false);
}));
break;
default:
root._events.remove.forEach((function(handler) {
return handler.cb(X, newpath, root);
}));
break;
}
};
var objects = deepProxy.objects = function(A, B, f, path, root) {
var Akeys = Object.keys(A);
var Bkeys = Object.keys(B);
Bkeys.forEach((function(b) {
var t_b = type(B[b]);
var old = A[b];
if (Akeys.indexOf(b) === -1) {
switch (t_b) {
case "undefined":
throw new Error("undefined type has key. this shouldn't happen?");
case "array":
case "object":
A[b] = f(B[b]);
break;
default:
A[b] = B[b];
}
onChange(path, b, root, old, B[b]);
return;
}
var t_a = type(A[b]);
if (t_a !== t_b) {
console.log("type changed from [%s] to [%s]", t_a, t_b);
switch (t_b) {
case "undefined":
throw new Error("first pass should never reveal undefined keys");
case "array":
A[b] = f(B[b]);
break;
case "object":
A[b] = f(B[b]);
break;
default:
A[b] = B[b];
break;
}
onChange(path, b, root, old, B[b]);
return;
}
if ([ "array", "object" ].indexOf(t_a) === -1) {
if (A[b] !== B[b]) {
A[b] = B[b];
onChange(path, b, root, old, B[b]);
}
return;
}
var nextPath = path.slice(0).concat(b);
if (t_a === "object") {
objects.call(root, A[b], B[b], f, nextPath, root);
} else {
deepProxy.arrays.call(root, A[b], B[b], f, nextPath, root);
}
}));
Akeys.forEach((function(a) {
var old = A[a];
if (a === "on" || a === "_events") {
return;
}
if (Bkeys.indexOf(a) === -1 || type(B[a]) === "undefined") {
onRemove(path, a, root, old, true);
delete A[a];
}
}));
return;
};
var arrays = deepProxy.arrays = function(A, B, f, path, root) {
var l_A = A.length;
var l_B = B.length;
if (l_A !== l_B) {
B.forEach((function(b, i) {
var t_a = type(A[i]);
var t_b = type(b);
var old = A[i];
if (t_a !== t_b) {
switch (t_b) {
case "undefined":
throw new Error("this should never happen");
case "object":
A[i] = f(b);
break;
case "array":
A[i] = f(b);
break;
default:
A[i] = b;
break;
}
onChange(path, i, root, old, b);
} else {
var nextPath = path.slice(0).concat(i);
switch (t_b) {
case "object":
objects.call(root, A[i], b, f, nextPath, root);
break;
case "array":
if (arrays.call(root, A[i], b, f, nextPath, root)) {
onChange(path, i, root, old, b);
}
break;
default:
if (b !== A[i]) {
A[i] = b;
onChange(path, i, root, old, b);
}
break;
}
}
}));
if (l_A > l_B) {
var i = l_B;
var old;
for (;i <= l_B; i++) {
old = A[i];
onRemove(path, i, root, old, true);
}
}
A.length = l_B;
return;
}
A.forEach((function(a, i) {
var t_a = type(a);
var t_b = type(B[i]);
var old = a;
if (t_a !== t_b) {
switch (t_b) {
case "undefined":
onRemove(path, i, root, old, true);
break;
case "object":
case "array":
A[i] = f(B[i]);
break;
default:
A[i] = B[i];
break;
}
onChange(path, i, root, old, B[i]);
return;
}
var nextPath = path.slice(0).concat(i);
switch (t_b) {
case "undefined":
throw new Error("existing key had type `undefined`. this should never happen");
case "object":
if (objects.call(root, A[i], B[i], f, nextPath, root)) {
onChange(path, i, root, old, B[i]);
}
break;
case "array":
if (arrays.call(root, A[i], B[i], f, nextPath, root)) {
onChange(path, i, root, old, B[i]);
}
break;
default:
if (A[i] !== B[i]) {
A[i] = B[i];
onChange(path, i, root, old, B[i]);
}
break;
}
}));
return;
};
deepProxy.update = function(A, B, cb) {
var t_A = type(A);
var t_B = type(B);
if (t_A !== t_B) {
throw new Error("Proxy updates can't result in type changes");
}
switch (t_B) {
case "array":
arrays.call(A, A, B, (function(obj) {
return create(obj, cb);
}), [], A);
break;
case "object":
objects.call(A, A, B, (function(obj) {
return create(obj, cb);
}), [], A);
break;
default:
throw new Error("unsupported realtime datatype:" + t_B);
}
};
return deepProxy;
}();
api.create = function(cfg) {
if (!DeepProxy.isProxyable(cfg.data, true)) {
throw new Error("unsupported datatype: " + DeepProxy.type(cfg.data));
}
ChainPad = cfg.ChainPad || window.ChainPad;
if (typeof ChainPad.SmartJSONTransformer !== "function") {
throw new Error("Please update ChainPad");
}
if (cfg.classic && !cfg.crypto) {
console.error("[chainpad-listmap] no crypto module provided. messages will not be encrypted");
cfg.crypto = {
encrypt: function(msg) {
return msg;
},
decrypt: function(msg) {
return msg;
}
};
}
var readOnly = cfg.readOnly;
var config = {
initialState: Sortify(cfg.data),
patchTransformer: ChainPad.SmartJSONTransformer,
validateContent: cfg.validateContent || function(content) {
try {
JSON.parse(content);
return true;
} catch (e) {
console.log(content);
console.error("Failed to parse, rejecting patch");
return false;
}
},
readOnly: cfg.readOnly,
userName: cfg.userName || "listmap",
Cache: cfg.Cache,
logLevel: typeof cfg.logLevel === "undefined" ? 0 : cfg.logLevel
};
if (cfg.classic) {
config.channel = cfg.channel;
config.crypto = cfg.crypto;
config.network = cfg.network;
config.websocketURL = cfg.websocketURL;
config.metadata = cfg.metadata || {
validateKey: cfg.validateKey,
owners: cfg.owners,
expire: cfg.expire
};
config.onRejected = cfg.onRejected;
}
var rt = {};
rt.metadata = {};
var realtime;
var proxy;
var initializing = true;
var ready = false;
var localTo;
var stringifier = isFakeProxy ? DeepProxy.stringifyFakeProxy : Sortify;
var onLocalFollowUp = function() {
var strung = stringifier(proxy);
try {
realtime.contentUpdate(strung);
} catch (e) {
proxy._events.error.forEach((function(handler) {
handler.cb({
type: "CHAINPAD",
error: e.message
});
}));
}
if (cfg.onLocal) {
cfg.onLocal();
}
};
var onLocal = config.onLocal = function(remote) {
if (initializing) {
return;
}
if (readOnly) {
return;
}
clearTimeout(localTo);
if (remote) {
return void onLocalFollowUp();
}
localTo = setTimeout(onLocalFollowUp);
};
var setterCb = function() {
if (!DeepProxy.remoteChangeFlag) {
onLocal();
}
};
proxy = DeepProxy.create(cfg.data, setterCb, true);
config.onInit = function(info) {
proxy._events.create.forEach((function(handler) {
handler.cb(info);
}));
};
config.onCacheReady = function(info) {
if (!realtime || realtime !== info.realtime) {
realtime = rt.realtime = info.realtime;
}
var userDoc = realtime.getUserDoc();
var parsed = JSON.parse(userDoc);
DeepProxy.update(proxy, parsed, setterCb);
DeepProxy.checkLocalChange(proxy, onLocal);
if (ready) {
return;
}
proxy._events.cacheready.forEach((function(handler) {
handler.cb(info);
}));
};
var idx = 0;
config.onReady = function(info) {
idx = -1;
if (ready) {
initializing = false;
config.onRemote();
proxy._events.reconnect.forEach((function(handler) {
handler.cb(info);
}));
return;
}
if (!realtime || realtime !== info.realtime) {
realtime = rt.realtime = info.realtime;
}
rt.metadata = info.metadata;
var userDoc = realtime.getUserDoc();
var parsed = JSON.parse(userDoc);
DeepProxy.update(proxy, parsed, setterCb);
DeepProxy.checkLocalChange(proxy, onLocal);
initializing = false;
ready = true;
proxy._events.ready.forEach((function(handler) {
handler.cb(info);
}));
};
config.onRemote = function() {
if (initializing) {
return;
}
var userDoc = realtime.getUserDoc();
var parsed = JSON.parse(userDoc);
DeepProxy.remoteChangeFlag = true;
DeepProxy.update(proxy, parsed, setterCb);
DeepProxy.remoteChangeFlag = false;
};
config.onMessage = function() {
if (idx === -1) {
return;
}
if (cfg.updateProgress) {
cfg.updateProgress({
progress: idx++
});
}
};
config.onAbort = function(info) {
proxy._events.disconnect.forEach((function(handler) {
handler.cb(info);
}));
};
config.onConnectionChange = function(info) {
if (info.state) {
initializing = true;
return;
}
proxy._events.disconnect.forEach((function(handler) {
handler.cb(info);
}));
};
config.onMetadataUpdate = function(metadata) {
rt.metadata = metadata;
if (typeof cfg.onMetadataUpdate === "function") {
cfg.onMetadataUpdate(metadata);
}
};
config.onError = function(info) {
proxy._events.error.forEach((function(handler) {
handler.cb(info);
}));
};
config.onChannelError = function(info) {
proxy._events.error.forEach((function(handler) {
handler.cb(info);
}));
};
if (cfg.common && typeof cfg.common.startRealtime === "function") {
realtime = rt.cpCnInner = cfg.common.startRealtime(config);
} else {
rt = Realtime.start(config);
}
rt.proxy = proxy;
rt.realtime = realtime;
var _setReadOnly = rt.setReadOnly;
rt.setReadOnly = function(state, crypto) {
readOnly = state;
if (_setReadOnly) {
_setReadOnly(state, crypto);
}
};
return rt;
};
return api;
};
if (module.exports) {
module.exports = factory(requireChainpadNetflux(), requireJson_sortify());
}
})();
})(chainpadListmap);
return chainpadListmap.exports;
}
var chainpadListmapExports = requireChainpadListmap();
function commonjsRequire(path) {
throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
}
var chainpad_dist$1 = {
exports: {}
};
var hasRequiredChainpad_dist;
function requireChainpad_dist() {
if (hasRequiredChainpad_dist) return chainpad_dist$1.exports;
hasRequiredChainpad_dist = 1;
(function(module, exports) {
(function() {
var r = function() {
var e = "function" == typeof commonjsRequire && commonjsRequire, r = function(i, o, u) {
o || (o = 0);
var n = r.resolve(i, o), t = r.m[o][n];
if (!t && e) {
if (t = e(n)) return t;
} else if (t && t.c && (o = t.c, n = t.m, t = r.m[o][t.m], !t)) throw new Error('failed to require "' + n + '" from ' + o);
if (!t) throw new Error('failed to require "' + i + '" from ' + u);
return t.exports || (t.exports = {}, t.call(t.exports, t, t.exports, r.relative(n, o))),
t.exports;
};
return r.resolve = function(e, n) {
var i = e, t = e + ".js", o = e + "/index.js";
return r.m[n][t] && t ? t : r.m[n][o] && o ? o : i;
}, r.relative = function(e, t) {
return function(n) {
if ("." != n.charAt(0)) return r(n, t, e);
var o = e.split("/"), f = n.split("/");
o.pop();
for (var i = 0; i < f.length; i++) {
var u = f[i];
".." == u ? o.pop() : "." != u && o.push(u);
}
return r(o.join("/"), t, e);
};
}, r;
}();
r.m = [];
r.m[0] = {
"json.sortify": {
c: 1,
m: "dist/JSON.sortify.js"
},
"fast-diff": {
c: 2,
m: "diff.js"
},
"Diff.js": function(module, exports, require) {
var FastDiff = require("fast-diff");
var transform = function(matches) {
var out = [];
var offset = 0;
var first = true;
var current = {
offset: 0,
toInsert: "",
toRemove: 0,
type: "Operation"
};
matches.forEach((function(el, i) {
if (el[0] === 0) {
if (!first) {
out.push(current);
offset = current.offset + current.toRemove;
current = {
offset,
toInsert: "",
toRemove: 0,
type: "Operation"
};
}
offset += el[1].length;
current.offset = offset;
} else if (el[0] === 1) {
current.toInsert = el[1];
} else {
current.toRemove = el[1].length;
}
if (i === matches.length - 1 && el[0] !== 0) {
out.push(current);
}
if (first) {
first = false;
}
}));
return out;
};
module.exports.diff = function(oldS, newS) {
return transform(FastDiff(oldS, newS));
};
},
"Patch.js": function(module, exports, require) {
var Common = require("./Common");
var Operation = require("./Operation");
var Sha = require("./sha256");
var Patch = module.exports;
var create = Patch.create = function(parentHash, isCheckpoint) {
var out = Object.freeze({
type: "Patch",
operations: [],
parentHash,
isCheckpoint: !!isCheckpoint,
mut: {
inverseOf: undefined
}
});
if (isCheckpoint) {
out.mut.inverseOf = out;
}
return out;
};
var check = Patch.check = function(patch, docLength_opt) {
Common.assert(patch.type === "Patch");
Common.assert(Array.isArray(patch.operations));
Common.assert(/^[0-9a-f]{64}$/.test(patch.parentHash));
for (var i = patch.operations.length - 1; i >= 0; i--) {
Operation.check(patch.operations[i], docLength_opt);
if (i > 0) {
Common.assert(!Operation.shouldMerge(patch.operations[i], patch.operations[i - 1]));
}
if (typeof docLength_opt === "number") {
docLength_opt += Operation.lengthChange(patch.operations[i]);
}
}
if (patch.isCheckpoint) {
Common.assert(patch.operations.length === 1);
Common.assert(patch.operations[0].offset === 0);
if (typeof docLength_opt === "number") {
Common.assert(!docLength_opt || patch.operations[0].toRemove === docLength_opt);
}
}
return patch;
};
Patch.toObj = function(patch) {
if (Common.PARANOIA) {
check(patch);
}
var out = new Array(patch.operations.length + 1);
var i;
for (i = 0; i < patch.operations.length; i++) {
out[i] = Operation.toObj(patch.operations[i]);
}
out[i] = patch.parentHash;
return out;
};
Patch.fromObj = function(obj, isCheckpoint) {
Common.assert(Array.isArray(obj) && obj.length > 0);
var patch = create(Sha.check(obj[obj.length - 1]), isCheckpoint);
var i;
for (i = 0; i < obj.length - 1; i++) {
patch.operations[i] = Operation.fromObj(obj[i]);
}
if (Common.PARANOIA) {
check(patch);
}
return patch;
};
var hash = function(text) {
return Sha.hex_sha256(text);
};
var addOperation = Patch.addOperation = function(patch, op) {
if (Common.PARANOIA) {
check(patch);
Operation.check(op);
}
for (var i = 0; i < patch.operations.length; i++) {
if (Operation.shouldMerge(patch.operations[i], op)) {
var maybeOp = Operation.merge(patch.operations[i], op);
patch.operations.splice(i, 1);
if (maybeOp === null) {
return;
}
op = maybeOp;
i--;
} else {
var out = Operation.rebase(patch.operations[i], op);
if (out === op) {
patch.operations.splice(i, 0, op);
return;
} else {
op = out;
}
}
}
patch.operations.push(op);
if (Common.PARANOIA) {
check(patch);
}
};
Patch.createCheckpoint = function(parentContent, checkpointContent, parentContentHash_opt) {
var op = Operation.create(0, parentContent.length, checkpointContent);
if (Common.PARANOIA && parentContentHash_opt) {
Common.assert(parentContentHash_opt === hash(parentContent));
}
parentContentHash_opt = parentContentHash_opt || hash(parentContent);
var out = create(parentContentHash_opt, true);
out.operations[0] = op;
return out;
};
var clone = Patch.clone = function(patch) {
if (Common.PARANOIA) {
check(patch);
}
var out = create(patch.parentHash, patch.isCheckpoint);
for (var i = 0; i < patch.operations.length; i++) {
out.operations[i] = patch.operations[i];
}
return out;
};
Patch.merge = function(oldPatch, newPatch) {
if (Common.PARANOIA) {
check(oldPatch);
check(newPatch);
}
if (oldPatch.isCheckpoint) {
Common.assert(newPatch.parentHash === oldPatch.parentHash);
if (newPatch.isCheckpoint) {
return create(oldPatch.parentHash);
}
return clone(newPatch);
} else if (newPatch.isCheckpoint) {
return clone(oldPatch);
}
oldPatch = clone(oldPatch);
for (var i = newPatch.operations.length - 1; i >= 0; i--) {
addOperation(oldPatch, newPatch.operations[i]);
}
return oldPatch;
};
Patch.apply = function(patch, doc) {
if (Common.PARANOIA) {
check(patch);
Common.assert(typeof doc === "string");
Common.assert(Sha.hex_sha256(doc) === patch.parentHash);
}
var newDoc = doc;
for (var i = patch.operations.length - 1; i >= 0; i--) {
newDoc = Operation.apply(patch.operations[i], newDoc);
}
return newDoc;
};
Patch.lengthChange = function(patch) {
if (Common.PARANOIA) {
check(patch);
}
var out = 0;
for (var i = 0; i < patch.operations.length; i++) {
out += Operation.lengthChange(patch.operations[i]);
}
return out;
};
Patch.invert = function(patch, doc) {
if (Common.PARANOIA) {
check(patch);
Common.assert(typeof doc === "string");
Common.assert(Sha.hex_sha256(doc) === patch.parentHash);
}
var newDoc = doc;
var operations = new Array(patch.operations.length);
for (var i = patch.operations.length - 1; i >= 0; i--) {
operations[i] = Operation.invert(patch.operations[i], newDoc);
newDoc = Operation.apply(patch.operations[i], newDoc);
}
var opOffsets = new Array(patch.operations.length);
(function() {
for (var i = operations.length - 1; i >= 0; i--) {
opOffsets[i] = operations[i].offset;
for (var j = i - 1; j >= 0; j--) {
opOffsets[i] += operations[j].toRemove - operations[j].toInsert.length;
}
}
})();
var rpatch = create(Sha.hex_sha256(newDoc), patch.isCheckpoint);
rpatch.operations.splice(0, rpatch.operations.length);
for (var j = 0; j < operations.length; j++) {
rpatch.operations[j] = Operation.create(opOffsets[j], operations[j].toRemove, operations[j].toInsert);
}
if (Common.PARANOIA) {
check(rpatch);
}
return rpatch;
};
Patch.simplify = function(patch, doc, operationSimplify) {
if (Common.PARANOIA) {
check(patch);
Common.assert(typeof doc === "string");
Common.assert(Sha.hex_sha256(doc) === patch.parentHash);
}
var spatch = create(patch.parentHash);
var newDoc = doc;
var outOps = [];
var j = 0;
for (var i = patch.operations.length - 1; i >= 0; i--) {
var outOp = operationSimplify(patch.operations[i], newDoc, Operation.simplify);
if (outOp) {
newDoc = Operation.apply(outOp, newDoc);
outOps[j++] = outOp;
}
}
Array.prototype.push.apply(spatch.operations, outOps.reverse());
if (!spatch.operations[0]) {
spatch.operations.shift();
}
if (Common.PARANOIA) {
check(spatch);
}
return spatch;
};
Patch.equals = function(patchA, patchB) {
if (patchA.operations.length !== patchB.operations.length) {
return false;
}
for (var i = 0; i < patchA.operations.length; i++) {
if (!Operation.equals(patchA.operations[i], patchB.operations[i])) {
return false;
}
}
return true;
};
var isCheckpointOp = function(op, text) {
return op.offset === 0 && op.toRemove === text.length && op.toInsert === text;
};
Patch.transform = function(toTransform, transformBy, doc, patchTransformer) {
if (Common.PARANOIA) {
check(toTransform, doc.length);
check(transformBy, doc.length);
if (Sha.hex_sha256(doc) !== toTransform.parentHash) {
throw new Error("wrong hash");
}
}
if (toTransform.parentHash !== transformBy.parentHash) {
throw new Error;
}
var afterTransformBy = Patch.apply(transformBy, doc);
var out = create(transformBy.mut.inverseOf ? transformBy.mut.inverseOf.parentHash : Sha.hex_sha256(afterTransformBy), toTransform.isCheckpoint);
if (transformBy.operations.length === 0) {
return clone(toTransform);
}
if (toTransform.operations.length === 0) {
if (toTransform.isCheckpoint) {
throw new Error;
}
return out;
}
if (toTransform.isCheckpoint || toTransform.operations.length === 1 && isCheckpointOp(toTransform.operations[0], doc)) {
throw new Error("Attempting to transform a checkpoint, this should not happen");
}
if (transformBy.operations.length === 1 && isCheckpointOp(transformBy.operations[0], doc)) {
if (!transformBy.isCheckpoint) {
throw new Error;
}
return toTransform;
}
if (transformBy.isCheckpoint) {
throw new Error;
}
var ops = patchTransformer(toTransform.operations, transformBy.operations, doc);
Array.prototype.push.apply(out.operations, ops);
if (Common.PARANOIA) {
check(out, afterTransformBy.length);
}
return out;
};
Patch.random = function(doc, opCount) {
Common.assert(typeof doc === "string");
opCount = opCount || Math.floor(Math.random() * 30) + 1;
var patch = create(Sha.hex_sha256(doc));
var docLength = doc.length;
while (opCount-- > 0) {
var op = Operation.random(docLength);
docLength += Operation.lengthChange(op);
addOperation(patch, op);
}
check(patch);
return patch;
};
Object.freeze(module.exports);
},
"SHA256.js": function(module, exports, require) {
(function() {
var chrsz = 8;
function safe_add(x, y) {
var lsw = (x & 65535) + (y & 65535);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return msw << 16 | lsw & 65535;
}
function S(X, n) {
return X >>> n | X << 32 - n;
}
function R(X, n) {
return X >>> n;
}
function Ch(x, y, z) {
return x & y ^ ~x & z;
}
function Maj(x, y, z) {
return x & y ^ x & z ^ y & z;
}
function Sigma0256(x) {
return S(x, 2) ^ S(x, 13) ^ S(x, 22);
}
function Sigma1256(x) {
return S(x, 6) ^ S(x, 11) ^ S(x, 25);
}
function Gamma0256(x) {
return S(x, 7) ^ S(x, 18) ^ R(x, 3);
}
function Gamma1256(x) {
return S(x, 17) ^ S(x, 19) ^ R(x, 10);
}
function newArray(n) {
var a = [];
for (;n > 0; n--) {
a.push(undefined);
}
return a;
}
function core_sha256(m, l) {
var K = [ 1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221, 3624381080, 310598401, 607225278, 1426881987, 1925078388, 2162078206, 2614888103, 3248222580, 3835390401, 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, 2554220882, 2821834349, 2952996808, 3210313671, 3336571891, 3584528711, 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, 2456956037, 2730485921, 2820302411, 3259730800, 3345764771, 3516065817, 3600352804, 4094571909, 275423344, 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, 1955562222, 2024104815, 2227730452, 2361852424, 2428436474, 2756734187, 3204031479, 3329325298 ];
var HASH = [ 1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225 ];
var W = newArray(64);
var a, b, c, d, e, f, g, h, i, j;
var T1, T2;
m[l >> 5] |= 128 << 24 - l % 32;
m[(l + 64 >> 9 << 4) + 15] = l;
for (var i = 0; i < m.length; i += 16) {
a = HASH[0];
b = HASH[1];
c = HASH[2];
d = HASH[3];
e = HASH[4];
f = HASH[5];
g = HASH[6];
h = HASH[7];
for (var j = 0; j < 64; j++) {
if (j < 16) {
W[j] = m[j + i];
} else {
W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
}
T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
T2 = safe_add(Sigma0256(a), Maj(a, b, c));
h = g;
g = f;
f = e;
e = safe_add(d, T1);
d = c;
c = b;
b = a;
a = safe_add(T1, T2);
}
HASH[0] = safe_add(a, HASH[0]);
HASH[1] = safe_add(b, HASH[1]);
HASH[2] = safe_add(c, HASH[2]);
HASH[3] = safe_add(d, HASH[3]);
HASH[4] = safe_add(e, HASH[4]);
HASH[5] = safe_add(f, HASH[5]);
HASH[6] = safe_add(g, HASH[6]);
HASH[7] = safe_add(h, HASH[7]);
}
return HASH;
}
function str2binb(str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for (var i = 0; i < str.length * chrsz; i += chrsz) bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << 24 - i % 32;
return bin;
}
function binb2hex(binarray) {
var hex_tab = "0123456789abcdef";
var str = "";
for (var i = 0; i < binarray.length * 4; i++) {
str += hex_tab.charAt(binarray[i >> 2] >> (3 - i % 4) * 8 + 4 & 15) + hex_tab.charAt(binarray[i >> 2] >> (3 - i % 4) * 8 & 15);
}
return str;
}
function hex_sha256(s) {
return binb2hex(core_sha256(str2binb(s), s.length * chrsz));
}
module.exports.hex_sha256 = hex_sha256;
})();
},
"Common.js": function(module, exports, require) {
module.exports.global = function() {
if (typeof self !== "undefined") {
return self;
}
if (typeof commonjsGlobal !== "undefined") {
return commonjsGlobal;
}
if (typeof window !== "undefined") {
return window;
}
throw new Error("no self, nor global, nor window");
}();
var cfg = function(name) {
if (typeof localStorage !== "undefined" && localStorage[name]) {
return localStorage[name];
}
return module.exports.global[name];
};
var PARANOIA = module.exports.PARANOIA = cfg("ChainPad_PARANOIA");
module.exports.VALIDATE_ENTIRE_CHAIN_EACH_MSG = cfg("ChainPad_VALIDATE_ENTIRE_CHAIN_EACH_MSG");
module.exports.TESTING = cfg("ChainPad_TESTING");
module.exports.assert = function(expr) {
if (!expr) {
throw new Error("Failed assertion");
}
};
module.exports.isUint = function(integer) {
return typeof integer === "number" && Math.floor(integer) === integer && integer >= 0;
};
module.exports.randomASCII = function(length) {
var content = [];
for (var i = 0; i < length; i++) {
content[i] = String.fromCharCode(Math.floor(Math.random() * 256) % 57 + 65);
}
return content.join("");
};
module.exports.strcmp = function(a, b) {
if (PARANOIA && typeof a !== "string") {
throw new Error;
}
if (PARANOIA && typeof b !== "string") {
throw new Error;
}
return a === b ? 0 : a > b ? 1 : -1;
};
Object.freeze(module.exports);
},
"sha256.js": function(module, exports, require) {
var asm_sha256 = require("./sha256/exports.js");
var old = require("./SHA256.js");
var Common = require("./Common");
var brokenTextEncode = function(str) {
var out = new Uint8Array(str.length);
for (var i = 0; i < str.length; i++) {
out[i] = str.charCodeAt(i) & 255;
}
return out;
};
module.exports.check = function(hex) {
if (typeof hex !== "string") {
throw new Error;
}
if (!/[a-f0-9]{64}/.test(hex)) {
throw new Error;
}
return hex;
};
module.exports.hex_sha256 = function(d) {
d = d + "";
var ret = asm_sha256.hex(brokenTextEncode(d));
if (Common.PARANOIA) {
var oldHash = old.hex_sha256(d);
if (oldHash !== ret) {
try {
throw new Error;
} catch (e) {
console.log({
hashErr: e,
badHash: d,
asmHasher: asm_sha256.hex,
oldHasher: old.hex_sha256
});
}
return oldHash;
}
}
return ret;
};
Object.freeze(module.exports);
},
"Message.js": function(module, exports, require) {
var Common = require("./Common");
var Patch = require("./Patch");
var Sha = require("./sha256");
var Message = module.exports;
var PATCH = Message.PATCH = 2;
var CHECKPOINT = Message.CHECKPOINT = 4;
var check = Message.check = function(msg) {
Common.assert(msg.type === "Message");
Common.assert(msg.messageType === PATCH || msg.messageType === CHECKPOINT);
Patch.check(msg.content);
Common.assert(typeof msg.lastMsgHash === "string");
return msg;
};
var DUMMY_HASH = "";
var create = Message.create = function(type, content, lastMsgHash) {
var msg = {
type: "Message",
messageType: type,
content,
lastMsgHash,
hashOf: DUMMY_HASH,
mut: {
parentCount: undefined,
isInitialMessage: false,
isFromMe: false,
parent: undefined,
time: undefined,
author: undefined,
serverHash: undefined
}
};
msg.hashOf = hashOf(msg);
if (Common.PARANOIA) {
check(msg);
}
return Object.freeze(msg);
};
var toString = Message.toStr = Message.toString = function(msg) {
if (Common.PARANOIA) {
check(msg);
}
if (msg.messageType === PATCH || msg.messageType === CHECKPOINT) {
if (!msg.content) {
throw new Error;
}
return JSON.stringify([ msg.messageType, Patch.toObj(msg.content), msg.lastMsgHash ]);
} else {
throw new Error;
}
};
Message.fromString = function(str) {
var obj = {};
if (typeof str === "object") {
obj = str;
str = str.msg;
}
var m = JSON.parse(str);
if (m[0] !== CHECKPOINT && m[0] !== PATCH) {
throw new Error("invalid message type " + m[0]);
}
var msg = create(m[0], Patch.fromObj(m[1], m[0] === CHECKPOINT), m[2]);
msg.mut.author = obj.author;
msg.mut.time = obj.time && new Date(obj.time);
msg.mut.serverHash = obj.serverHash;
return Object.freeze(msg);
};
var hashOf = Message.hashOf = function(msg) {
if (Common.PARANOIA) {
check(msg);
}
var hash = Sha.hex_sha256(toString(msg));
return hash;
};
Object.freeze(module.exports);
},
"ChainPad.js": function(module, exports, require) {
var Common = module.exports.Common = require("./Common");
var Operation = module.exports.Operation = require("./Operation");
var Patch = module.exports.Patch = require("./Patch");
var Message = module.exports.Message = require("./Message");
var Sha = module.exports.Sha = require("./sha256");
var Diff = module.exports.Diff = require("./Diff");
var TextTransformer = module.exports.TextTransformer = require("./transform/TextTransformer");
module.exports.NaiveJSONTransformer = require("./transform/NaiveJSONTransformer");
module.exports.SmartJSONTransformer = require("./transform/SmartJSONTransformer");
var EMPTY_STR_HASH = module.exports.EMPTY_STR_HASH = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
var ZERO = "0000000000000000000000000000000000000000000000000000000000000000";
var DEFAULT_CHECKPOINT_INTERVAL = 50;
var DEFAULT_AVERAGE_SYNC_MILLISECONDS = 300;
var DEFAULT_STRICT_CHECKPOINT_VALIDATION = false;
var debug = function(realtime, msg) {
if (realtime.logLevel > 1) {
console.log("[" + realtime.userName + "] " + msg);
}
};
var warn = function(realtime, msg) {
if (realtime.logLevel > 0) {
console.error("[" + realtime.userName + "] " + msg);
}
};
var schedule = function(realtime, func, timeout) {
if (realtime.aborted) {
return;
}
if (!timeout) {
timeout = Math.floor(Math.random() * 2 * realtime.config.avgSyncMilliseconds);
}
var to = setTimeout((function() {
realtime.schedules.splice(realtime.schedules.indexOf(to), 1);
func();
}), timeout);
realtime.schedules.push(to);
return to;
};
var unschedule = function(realtime, schedule) {
var index = realtime.schedules.indexOf(schedule);
if (index > -1) {
realtime.schedules.splice(index, 1);
}
clearTimeout(schedule);
};
var onMessage = function(realtime, message, callback) {
if (!realtime.messageHandlers.length) {
callback("no onMessage() handler registered");
}
try {
realtime.messageHandlers.forEach((function(handler) {
handler(message, (function() {
callback.apply(null, arguments);
callback = function() {};
}));
}));
} catch (e) {
callback(e.stack);
}
};
var sendMessage = function(realtime, msg, callback, timeSent) {
var strMsg = Message.toStr(msg);
onMessage(realtime, strMsg, (function(err) {
if (err) {
debug(realtime, "Posting to server failed [" + err + "]");
realtime.pending = null;
realtime.syncSchedule = schedule(realtime, (function() {
sync(realtime);
}));
} else {
var pending = realtime.pending;
realtime.pending = null;
if (!pending) {
throw new Error;
}
Common.assert(pending.hash === msg.hashOf);
if (handleMessage(realtime, strMsg, true)) {
realtime.timeOfLastSuccess = +new Date;
realtime.lag = +new Date - pending.timeSent;
} else {
debug(realtime, "Our message [" + msg.hashOf + "] failed validation");
}
pending.callback();
}
}));
if (realtime.pending) {
throw new Error("there is already a pending message");
}
if (realtime.timeOfLastSuccess === -1) {
realtime.timeOfLastSuccess = +new Date;
}
realtime.pending = {
hash: msg.hashOf,
timeSent: +new Date,
callback: function() {
realtime.syncSchedule = schedule(realtime, (function() {
sync(realtime);
}), 0);
callback();
}
};
if (Common.PARANOIA) {
check(realtime);
}
};
var settle = function(realtime) {
var onSettle = realtime.onSettle;
realtime.onSettle = [];
onSettle.forEach((function(handler) {
try {
handler();
} catch (e) {
warn(realtime, "Error in onSettle handler [" + e.stack + "]");
}
}));
};
var inversePatch = function(patch) {
if (!patch.mut.inverseOf) {
throw new Error;
}
return patch.mut.inverseOf;
};
var sync = function(realtime, timeSent) {
if (Common.PARANOIA) {
check(realtime);
}
if (realtime.syncSchedule && !realtime.pending) {
unschedule(realtime, realtime.syncSchedule);
realtime.syncSchedule = null;
} else {
return;
}
realtime.uncommitted = Patch.simplify(realtime.uncommitted, realtime.authDoc, realtime.config.operationSimplify);
if (realtime.uncommitted.operations.length === 0) {
settle(realtime);
realtime.timeOfLastSuccess = +new Date;
realtime.syncSchedule = schedule(realtime, (function() {
sync(realtime);
}));
return;
}
var pc = parentCount(realtime, realtime.best) + 1;
if (pc % realtime.config.checkpointInterval === 0) {
var best = realtime.best;
debug(realtime, "Sending checkpoint (interval [" + realtime.config.checkpointInterval + "]) patch no [" + pc + "]");
debug(realtime, parentCount(realtime, realtime.best));
if (!best || !best.content || !inversePatch(best.content)) {
throw new Error;
}
var cpp = Patch.createCheckpoint(realtime.authDoc, realtime.authDoc, inversePatch(best.content).parentHash);
var cp = Message.create(Message.CHECKPOINT, cpp, best.hashOf);
sendMessage(realtime, cp, (function() {
debug(realtime, "Checkpoint sent and accepted");
}));
return;
}
var msg;
if (realtime.setContentPatch) {
msg = realtime.setContentPatch;
} else {
msg = Message.create(Message.PATCH, realtime.uncommitted, realtime.best.hashOf);
}
sendMessage(realtime, msg, (function() {
if (realtime.setContentPatch) {
debug(realtime, "initial Ack received [" + msg.hashOf + "]");
realtime.setContentPatch = null;
}
}));
};
var storeMessage = function(realtime, msg) {
Common.assert(msg.lastMsgHash);
Common.assert(msg.hashOf);
realtime.messages[msg.hashOf] = msg;
(realtime.messagesByParent[msg.lastMsgHash] = realtime.messagesByParent[msg.lastMsgHash] || []).push(msg);
};
var forgetMessage = function(realtime, msg) {
Common.assert(msg.lastMsgHash);
Common.assert(msg.hashOf);
delete realtime.messages[msg.hashOf];
var list = realtime.messagesByParent[msg.lastMsgHash];
Common.assert(list.indexOf(msg) > -1);
list.splice(list.indexOf(msg), 1);
if (list.length === 0) {
delete realtime.messagesByParent[msg.lastMsgHash];
}
var children = realtime.messagesByParent[msg.hashOf];
if (children) {
for (var i = 0; i < children.length; i++) {
delete children[i].mut.parent;
}
}
};
var create = function(config) {
var zeroPatch = Patch.create(EMPTY_STR_HASH);
mkInverse(zeroPatch, "");
var zeroMsg = Message.create(Message.PATCH, zeroPatch, ZERO);
zeroMsg.mut.parentCount = 0;
zeroMsg.mut.isInitialMessage = true;
var best = zeroMsg;
var initMsg;
if (config.initialState !== "") {
var initPatch = Patch.create(EMPTY_STR_HASH);
Patch.addOperation(initPatch, Operation.create(0, 0, config.initialState));
mkInverse(initPatch, "");
initMsg = Message.create(Message.PATCH, initPatch, zeroMsg.hashOf);
initMsg.mut.isInitialMessage = true;
best = initMsg;
}
var realtime = {
type: "ChainPad",
authDoc: config.initialState,
config,
logLevel: config.logLevel,
uncommitted: Patch.create(inversePatch(best.content).parentHash),
patchHandlers: [],
changeHandlers: [],
messageHandlers: [],
schedules: [],
aborted: false,
syncSchedule: -2,
userInterfaceContent: config.initialState,
setContentPatch: initMsg,
pending: undefined,
messages: {},
messagesByParent: {},
rootMessage: zeroMsg,
onSettle: [],
userName: config.userName,
best,
lag: 0,
timeOfLastSuccess: -1
};
storeMessage(realtime, zeroMsg);
if (initMsg) {
storeMessage(realtime, initMsg);
}
return realtime;
};
var getParent = function(realtime, message) {
var parent = message.mut.parent = message.mut.parent || realtime.messages[message.lastMsgHash];
return parent;
};
var check = function(realtime) {
Common.assert(realtime.type === "ChainPad");
Common.assert(typeof realtime.authDoc === "string");
Patch.check(realtime.uncommitted, realtime.authDoc.length);
var uiDoc = Patch.apply(realtime.uncommitted, realtime.authDoc);
Common.assert(uiDoc.length === uncommittedDocLength(realtime));
if (realtime.userInterfaceContent !== "") {
Common.assert(uiDoc === realtime.userInterfaceContent);
}
if (!Common.VALIDATE_ENTIRE_CHAIN_EACH_MSG) {
return;
}
var doc = realtime.authDoc;
var patchMsg = realtime.best;
Common.assert(inversePatch(patchMsg.content).parentHash === realtime.uncommitted.parentHash);
var patches = [];
do {
patches.push(patchMsg);
doc = Patch.apply(inversePatch(patchMsg.content), doc);
} while (patchMsg = getParent(realtime, patchMsg));
if (realtime.rootMessage.content.isCheckpoint) {
if (doc !== realtime.rootMessage.content.operations[0].toInsert) {
throw new Error;
}
} else if (doc !== "") {
throw new Error;
}
while (patchMsg = patches.pop()) {
doc = Patch.apply(patchMsg.content, doc);
}
Common.assert(doc === realtime.authDoc);
};
var uncommittedDocLength = function(realtime) {
return realtime.authDoc.length + Patch.lengthChange(realtime.uncommitted);
};
var doOperation = function(realtime, op) {
if (Common.PARANOIA) {
check(realtime);
realtime.userInterfaceContent = Operation.apply(op, realtime.userInterfaceContent);
}
Operation.check(op, uncommittedDocLength(realtime));
Patch.addOperation(realtime.uncommitted, op);
};
var doPatch = function(realtime, patch) {
if (Common.PARANOIA) {
check(realtime);
Common.assert(Patch.invert(realtime.uncommitted, realtime.authDoc).parentHash === patch.parentHash);
realtime.userInterfaceContent = Patch.apply(patch, realtime.userInterfaceContent);
}
Patch.check(patch, uncommittedDocLength(realtime));
realtime.uncommitted = Patch.merge(realtime.uncommitted, patch);
};
var isAncestorOf = function(realtime, ancestor, decendent) {
if (!ancestor) {
return false;
}
for (;;) {
if (!decendent) {
return false;
}
if (ancestor === decendent) {
return true;
}
decendent = getParent(realtime, decendent);
}
};
var parentCount = function(realtime, message) {
if (typeof message.mut.parentCount === "number") {
return message.mut.parentCount;
}
var msgs = [];
for (;typeof message.mut.parentCount !== "number"; message = getParent(realtime, message)) {
if (!message) {
if (message === realtime.rootMessage) {
throw new Error("root message does not have parent count");
}
throw new Error("parentCount called on unlinked message");
}
msgs.unshift(message);
}
var pc = message.mut.parentCount;
for (var i = 0; i < msgs.length; i++) {
msgs[i].mut.parentCount = ++pc;
}
return pc;
};
var applyPatch = function(realtime, isFromMe, patch) {
Common.assert(patch);
var newAuthDoc;
if (isFromMe) {
Common.assert(patch.parentHash === realtime.uncommitted.parentHash);
realtime.uncommitted = Patch.merge(inversePatch(patch), realtime.uncommitted);
} else {
realtime.uncommitted = Patch.transform(realtime.uncommitted, patch, realtime.authDoc, realtime.config.patchTransformer);
if (realtime.config.validateContent) {
newAuthDoc = Patch.apply(patch, realtime.authDoc);
var userDoc = Patch.apply(realtime.uncommitted, newAuthDoc);
if (!realtime.config.validateContent(userDoc)) {
warn(realtime, "Transformed patch is not valid");
realtime.uncommitted = Patch.create(Sha.hex_sha256(realtime.authDoc));
}
}
}
Common.assert(realtime.uncommitted.parentHash === inversePatch(patch).parentHash);
realtime.authDoc = newAuthDoc || Patch.apply(patch, realtime.authDoc);
if (Common.PARANOIA) {
Common.assert(realtime.uncommitted.parentHash === inversePatch(patch).parentHash);
Common.assert(Sha.hex_sha256(realtime.authDoc) === realtime.uncommitted.parentHash);
realtime.userInterfaceContent = Patch.apply(realtime.uncommitted, realtime.authDoc);
}
};
var revertPatch = function(realtime, isFromMe, patch) {
applyPatch(realtime, isFromMe, inversePatch(patch));
};
var getBestChild = function(realtime, msg) {
var best = msg;
(realtime.messagesByParent[msg.hashOf] || []).forEach((function(child) {
Common.assert(child.lastMsgHash === msg.hashOf);
child = getBestChild(realtime, child);
if (parentCount(realtime, child) > parentCount(realtime, best)) {
best = child;
}
}));
return best;
};
var pushUIPatch = function(realtime, patch) {
if (!patch.operations.length) {
return;
}
realtime.patchHandlers.forEach((function(handler) {
handler(patch);
}));
realtime.changeHandlers.forEach((function(handler) {
patch.operations.forEach((function(op) {
handler(op.offset, op.toRemove, op.toInsert);
}));
}));
};
var validContent = function(realtime, contentGetter) {
try {
return realtime.config.validateContent(contentGetter());
} catch (e) {
warn(realtime, "Error in content validator [" + e.stack + "]");
}
return false;
};
var forEachParent = function(realtime, patch, callback) {
for (var m = getParent(realtime, patch); m; m = getParent(realtime, m)) {
if (callback(m) === false) {
return;
}
}
};
var mkInverse = function(patch, content) {
if (patch.mut.inverseOf) {
return;
}
var inverse = patch.mut.inverseOf = Patch.invert(patch, content);
inverse.mut.inverseOf = patch;
};
var handleMessage = function(realtime, msgStr, isFromMe) {
if (Common.PARANOIA) {
check(realtime);
}
var msg = Message.fromString(msgStr);
debug(realtime, JSON.stringify([ msg.hashOf, msg.content.operations ]));
if (realtime.messages[msg.hashOf]) {
if (realtime.setContentPatch && realtime.setContentPatch.hashOf === msg.hashOf) {
realtime.setContentPatch = null;
} else {
if (msg.content.isCheckpoint) {
debug(realtime, "[" + (isFromMe ? "our" : "their") + "] Checkpoint [" + msg.hashOf + "] is already known");
return true;
}
debug(realtime, "Patch [" + msg.hashOf + "] is already known");
}
if (Common.PARANOIA) {
check(realtime);
}
return;
}
if (msg.content.isCheckpoint && !validContent(realtime, (function() {
return msg.content.operations[0].toInsert;
}))) {
debug(realtime, "Checkpoint [" + msg.hashOf + "] failed content validation");
return;
}
storeMessage(realtime, msg);
if (!isAncestorOf(realtime, realtime.rootMessage, msg)) {
if (msg.content.isCheckpoint && realtime.best.mut.isInitialMessage) {
debug(realtime, "applying checkpoint [" + msg.hashOf + "]");
var userDoc = Patch.apply(realtime.uncommitted, realtime.authDoc);
Common.assert(!Common.PARANOIA || realtime.userInterfaceContent === userDoc);
var fixUserDocPatch = Patch.invert(realtime.uncommitted, realtime.authDoc);
Patch.addOperation(fixUserDocPatch, Operation.create(0, realtime.authDoc.length, msg.content.operations[0].toInsert));
fixUserDocPatch = Patch.simplify(fixUserDocPatch, userDoc, realtime.config.operationSimplify);
msg.mut.parentCount = 0;
realtime.rootMessage = realtime.best = msg;
realtime.authDoc = msg.content.operations[0].toInsert;
realtime.uncommitted = Patch.create(Sha.hex_sha256(realtime.authDoc));
pushUIPatch(realtime, fixUserDocPatch);
if (Common.PARANOIA) {
realtime.userInterfaceContent = realtime.authDoc;
}
return true;
} else {
debug(realtime, "Patch [" + msg.hashOf + "] not connected to root (parent: [" + msg.lastMsgHash + "])");
if (Common.PARANOIA) {
check(realtime);
}
return;
}
}
msg = getBestChild(realtime, msg);
msg.mut.isFromMe = isFromMe;
var patch = msg.content;
var toRevert = [];
var commonAncestor = realtime.best;
if (!isAncestorOf(realtime, realtime.best, msg)) {
var pcBest = parentCount(realtime, realtime.best);
var pcMsg = parentCount(realtime, msg);
if (pcBest < pcMsg || pcBest === pcMsg && Common.strcmp(realtime.best.hashOf, msg.hashOf) > 0) {
while (commonAncestor && !isAncestorOf(realtime, commonAncestor, msg)) {
toRevert.push(commonAncestor);
commonAncestor = getParent(realtime, commonAncestor);
}
Common.assert(commonAncestor);
debug(realtime, "Patch [" + msg.hashOf + "] better than best chain, switching");
} else {
debug(realtime, "Patch [" + msg.hashOf + "] chain is [" + pcMsg + "] best chain is [" + pcBest + "]");
if (Common.PARANOIA) {
check(realtime);
}
return true;
}
}
var toApply = [];
var current = msg;
do {
toApply.unshift(current);
current = getParent(realtime, current);
Common.assert(current);
} while (current !== commonAncestor);
var authDocAtTimeOfPatch = realtime.authDoc;
toRevert.forEach((function(tr) {
authDocAtTimeOfPatch = Patch.apply(inversePatch(tr.content), authDocAtTimeOfPatch);
}));
toApply.forEach((function(ta, i) {
if (i === toApply.length - 1) {
return;
}
mkInverse(ta.content, authDocAtTimeOfPatch);
authDocAtTimeOfPatch = Patch.apply(ta.content, authDocAtTimeOfPatch);
}));
var headAtTimeOfPatch = realtime.best;
if (toApply.length > 1) {
headAtTimeOfPatch = toApply[toApply.length - 2];
Common.assert(headAtTimeOfPatch);
} else if (toRevert.length) {
headAtTimeOfPatch = getParent(realtime, toRevert[toRevert.length - 1]);
Common.assert(headAtTimeOfPatch);
}
Common.assert(inversePatch(headAtTimeOfPatch.content).parentHash);
Common.assert(!Common.PARANOIA || inversePatch(headAtTimeOfPatch.content).parentHash === Sha.hex_sha256(authDocAtTimeOfPatch));
if (inversePatch(headAtTimeOfPatch.content).parentHash !== patch.parentHash) {
debug(realtime, "patch [" + msg.hashOf + "] parentHash is not valid");
if (Common.PARANOIA) {
check(realtime);
}
if (Common.TESTING) {
throw new Error;
}
forgetMessage(realtime, msg);
return;
}
if (patch.isCheckpoint && realtime.config.noPrune) ; else if (patch.isCheckpoint) {
var checkpointP;
forEachParent(realtime, msg, (function(m) {
if (m.content.isCheckpoint) {
if (checkpointP) {
checkpointP = m;
return false;
}
checkpointP = m;
}
}));
if (checkpointP && checkpointP !== realtime.rootMessage) {
var point = parentCount(realtime, checkpointP);
if (realtime.config.strictCheckpointValidation && point % realtime.config.checkpointInterval !== 0) {
debug(realtime, "checkpoint [" + msg.hashOf + "] at invalid point [" + point + "]");
if (Common.PARANOIA) {
check(realtime);
}
if (Common.TESTING) {
throw new Error;
}
forgetMessage(realtime, msg);
return;
}
debug(realtime, "checkpoint [" + msg.hashOf + "]");
forEachParent(realtime, checkpointP, (function(m) {
debug(realtime, "pruning [" + m.hashOf + "]");
forgetMessage(realtime, m);
}));
realtime.rootMessage = checkpointP;
}
} else {
var simplePatch = Patch.simplify(patch, authDocAtTimeOfPatch, realtime.config.operationSimplify);
if (!Patch.equals(simplePatch, patch)) {
debug(realtime, "patch [" + msg.hashOf + "] can be simplified");
if (Common.PARANOIA) {
check(realtime);
}
if (Common.TESTING) {
throw new Error;
}
forgetMessage(realtime, msg);
return;
}
if (!validContent(realtime, (function() {
return Patch.apply(patch, authDocAtTimeOfPatch);
}))) {
debug(realtime, "Patch [" + msg.hashOf + "] failed content validation");
return;
}
}
mkInverse(patch, authDocAtTimeOfPatch);
realtime.uncommitted = Patch.simplify(realtime.uncommitted, realtime.authDoc, realtime.config.operationSimplify);
var oldUserInterfaceContent = Patch.apply(realtime.uncommitted, realtime.authDoc);
if (Common.PARANOIA) {
Common.assert(oldUserInterfaceContent === realtime.userInterfaceContent);
}
var uncommittedPatch = Patch.invert(realtime.uncommitted, realtime.authDoc);
toRevert.forEach((function(tr) {
debug(realtime, "reverting [" + tr.hashOf + "]");
if (tr.mut.isFromMe) {
debug(realtime, "reverting patch 'from me' [" + JSON.stringify(tr.content.operations) + "]");
}
uncommittedPatch = Patch.merge(uncommittedPatch, inversePatch(tr.content));
revertPatch(realtime, tr.mut.isFromMe, tr.content);
}));
toApply.forEach((function(ta) {
debug(realtime, "applying [" + ta.hashOf + "]");
uncommittedPatch = Patch.merge(uncommittedPatch, ta.content);
applyPatch(realtime, ta.mut.isFromMe, ta.content);
}));
uncommittedPatch = Patch.merge(uncommittedPatch, realtime.uncommitted);
uncommittedPatch = Patch.simplify(uncommittedPatch, oldUserInterfaceContent, realtime.config.operationSimplify);
realtime.best = msg;
if (Common.PARANOIA) {
var newUserInterfaceContent = Patch.apply(uncommittedPatch, oldUserInterfaceContent);
Common.assert(realtime.userInterfaceContent.length === uncommittedDocLength(realtime));
Common.assert(newUserInterfaceContent === realtime.userInterfaceContent);
}
pushUIPatch(realtime, uncommittedPatch);
if (!realtime.uncommitted.operations.length) {
settle(realtime);
}
if (Common.PARANOIA) {
check(realtime);
}
return true;
};
var getDepthOfState = function(content, minDepth, realtime) {
Common.assert(typeof content === "string");
minDepth = minDepth || 0;
if (minDepth === 0 && realtime.authDoc === content) {
return 0;
}
var hash = Sha.hex_sha256(content);
var patchMsg = realtime.best;
var depth = 0;
do {
if (depth < minDepth) ; else {
if (patchMsg.content.parentHash === hash) {
return depth + 1;
}
}
depth++;
} while (patchMsg = getParent(realtime, patchMsg));
return -1;
};
var getContentAtState = function(realtime, msg) {
var patches = [ msg ];
while (patches[0] !== realtime.rootMessage) {
var parent = getParent(realtime, patches[0]);
if (!parent) {
return {
error: "not connected to root",
doc: undefined
};
}
patches.unshift(parent);
}
var doc = "";
if (realtime.rootMessage.content.operations.length) {
Common.assert(realtime.rootMessage.content.operations.length === 1);
doc = realtime.rootMessage.content.operations[0].toInsert;
}
for (var i = 1; i < patches.length; i++) {
doc = Patch.apply(patches[i].content, doc);
}
return {
error: undefined,
doc
};
};
var wrapMessage = function(realtime, msg) {
return Object.freeze({
type: "Block",
hashOf: msg.hashOf,
lastMsgHash: msg.lastMsgHash,
isCheckpoint: !!msg.content.isCheckpoint,
isFromMe: msg.mut && msg.mut.isFromMe,
author: msg.mut && msg.mut.author,
serverHash: msg.mut && msg.mut.serverHash,
time: msg.mut && msg.mut.time,
getParent: function() {
var parentMsg = getParent(realtime, msg);
if (parentMsg) {
return wrapMessage(realtime, parentMsg);
}
},
getContent: function() {
return getContentAtState(realtime, msg);
},
getPatch: function() {
return Patch.clone(msg.content);
},
getInversePatch: function() {
return Patch.clone(inversePatch(msg.content));
},
equals: function(block, msgOpt) {
if (msgOpt) {
return msg === msgOpt;
}
if (!block || typeof block !== "object" || block.type !== "Block") {
return false;
}
return block.equals(block, msg);
}
});
};
var mkConfig = function(config) {
config = config || {};
if (config.transformFunction) {
throw new Error("chainpad config transformFunction is nolonger used");
}
return Object.freeze({
initialState: config.initialState || "",
checkpointInterval: config.checkpointInterval || DEFAULT_CHECKPOINT_INTERVAL,
avgSyncMilliseconds: config.avgSyncMilliseconds || DEFAULT_AVERAGE_SYNC_MILLISECONDS,
strictCheckpointValidation: config.strictCheckpointValidation || DEFAULT_STRICT_CHECKPOINT_VALIDATION,
operationSimplify: config.operationSimplify || Operation.simplify,
logLevel: typeof config.logLevel === "number" ? config.logLevel : 2,
noPrune: config.noPrune,
patchTransformer: config.patchTransformer || TextTransformer,
userName: config.userName || "anonymous",
validateContent: config.validateContent || function(x) {
return true;
},
diffFunction: config.diffFunction || function(strA, strB) {
return Diff.diff(strA, strB);
}
});
};
module.exports.create = function(conf) {
var realtime = create(mkConfig(conf));
var out = {
onPatch: function(handler) {
Common.assert(typeof handler === "function");
realtime.patchHandlers.push(handler);
},
patch: function(patch, x, y) {
if (typeof patch === "number") {
if (typeof x !== "number" || typeof y !== "string") {
throw new Error;
}
out.change(patch, x, y);
return;
}
doPatch(realtime, patch);
},
onChange: function(handler) {
Common.assert(typeof handler === "function");
realtime.changeHandlers.push(handler);
},
change: function(offset, count, chars) {
if (count === 0 && chars === "") {
return;
}
doOperation(realtime, Operation.create(offset, count, chars));
},
contentUpdate: function(newContent) {
var ops = realtime.config.diffFunction(realtime.authDoc, newContent);
var uncommitted = Patch.create(realtime.uncommitted.parentHash);
Array.prototype.push.apply(uncommitted.operations, ops);
realtime.uncommitted = uncommitted;
},
onMessage: function(handler) {
Common.assert(typeof handler === "function");
realtime.messageHandlers.push(handler);
},
message: function(message) {
handleMessage(realtime, message, false);
},
start: function() {
realtime.aborted = false;
if (realtime.syncSchedule) {
unschedule(realtime, realtime.syncSchedule);
}
realtime.pending = null;
realtime.syncSchedule = schedule(realtime, (function() {
sync(realtime);
}));
},
abort: function() {
realtime.aborted = true;
realtime.schedules.forEach((function(s) {
clearTimeout(s);
}));
},
sync: function() {
sync(realtime);
},
getAuthDoc: function() {
return realtime.authDoc;
},
getUserDoc: function() {
return Patch.apply(realtime.uncommitted, realtime.authDoc);
},
getDepthOfState: function(content, minDepth) {
return getDepthOfState(content, minDepth, realtime);
},
onSettle: function(handler) {
Common.assert(typeof handler === "function");
realtime.onSettle.push(handler);
},
getAuthBlock: function() {
return wrapMessage(realtime, realtime.best);
},
getBlockForHash: function(hash) {
Common.assert(typeof hash === "string");
var msg = realtime.messages[hash];
if (msg) {
return wrapMessage(realtime, msg);
}
},
getLag: function() {
var isPending = !!realtime.pending;
var lag = realtime.lag;
if (realtime.pending) {
lag = +new Date - realtime.timeOfLastSuccess;
}
return {
pending: isPending,
lag,
active: !realtime.aborted && realtime.syncSchedule !== -2
};
},
_: undefined
};
out._ = realtime;
return Object.freeze(out);
};
Object.freeze(module.exports);
},
"Operation.js": function(module, exports, require) {
var Common = require("./Common");
var Operation = module.exports;
var check = Operation.check = function(op, docLength_opt) {
Common.assert(op.type === "Operation");
if (!Common.isUint(op.offset)) {
throw new Error;
}
if (!Common.isUint(op.toRemove)) {
throw new Error;
}
if (typeof op.toInsert !== "string") {
throw new Error;
}
if (op.toRemove < 1 && op.toInsert.length < 1) {
throw new Error;
}
Common.assert(typeof docLength_opt !== "number" || op.offset + op.toRemove <= docLength_opt);
return op;
};
var create = Operation.create = function(offset, toRemove, toInsert) {
var out = {
type: "Operation",
offset: offset || 0,
toRemove: toRemove || 0,
toInsert: toInsert || ""
};
if (Common.PARANOIA) {
check(out);
}
return Object.freeze(out);
};
Operation.toObj = function(op) {
if (Common.PARANOIA) {
check(op);
}
return [ op.offset, op.toRemove, op.toInsert ];
};
Operation.fromObj = function(obj) {
Common.assert(Array.isArray(obj) && obj.length === 3);
return create(obj[0], obj[1], obj[2]);
};
var apply = Operation.apply = function(op, doc) {
if (Common.PARANOIA) {
Common.assert(typeof doc === "string");
check(op, doc.length);
}
return doc.substring(0, op.offset) + op.toInsert + doc.substring(op.offset + op.toRemove);
};
Operation.applyMulti = function(ops, doc) {
for (var i = ops.length - 1; i >= 0; i--) {
doc = apply(ops[i], doc);
}
return doc;
};
var invert = Operation.invert = function(op, doc) {
if (Common.PARANOIA) {
check(op);
Common.assert(typeof doc === "string");
Common.assert(op.offset + op.toRemove <= doc.length);
}
return create(op.offset, op.toInsert.length, (" " + doc.substring(op.offset, op.offset + op.toRemove)).slice(1));
};
var surrogatePattern = /[\uD800-\uDBFF]|[\uDC00-\uDFFF]/;
var hasSurrogate = Operation.hasSurrogate = function(str) {
return surrogatePattern.test(str);
};
Operation.simplify = function(op, doc) {
if (Common.PARANOIA) {
check(op);
Common.assert(typeof doc === "string");
Common.assert(op.offset + op.toRemove <= doc.length);
}
var rop = invert(op, doc);
var minLen = Math.min(op.toInsert.length, rop.toInsert.length);
var i = 0;
while (i < minLen && rop.toInsert[i] === op.toInsert[i]) {
if (hasSurrogate(rop.toInsert[i]) || hasSurrogate(op.toInsert[i])) {
if (op.toInsert[i + 1] === rop.toInsert[i + 1]) {
i++;
} else {
break;
}
}
i++;
}
var opOffset = op.offset + i;
var opToRemove = op.toRemove - i;
var opToInsert = op.toInsert.substring(i);
var ropToInsert = rop.toInsert.substring(i);
if (ropToInsert.length === opToInsert.length) {
for (i = ropToInsert.length - 1; i >= 0 && ropToInsert[i] === opToInsert[i]; i--) ;
opToInsert = opToInsert.substring(0, i + 1);
opToRemove = i + 1;
}
if (opToRemove === 0 && opToInsert.length === 0) {
return null;
}
return create(opOffset, opToRemove, opToInsert);
};
Operation.equals = function(opA, opB) {
return opA.toRemove === opB.toRemove && opA.toInsert === opB.toInsert && opA.offset === opB.offset;
};
Operation.lengthChange = function(op) {
if (Common.PARANOIA) {
check(op);
}
return op.toInsert.length - op.toRemove;
};
Operation.merge = function(oldOpOrig, newOpOrig) {
if (Common.PARANOIA) {
check(newOpOrig);
check(oldOpOrig);
}
var oldOp_offset = oldOpOrig.offset;
var oldOp_toRemove = oldOpOrig.toRemove;
var oldOp_toInsert = oldOpOrig.toInsert;
var newOp_offset = newOpOrig.offset;
var newOp_toRemove = newOpOrig.toRemove;
var newOp_toInsert = newOpOrig.toInsert;
var offsetDiff = newOp_offset - oldOp_offset;
if (newOp_toRemove > 0) {
var origOldInsert = oldOp_toInsert;
oldOp_toInsert = oldOp_toInsert.substring(0, offsetDiff) + oldOp_toInsert.substring(offsetDiff + newOp_toRemove);
newOp_toRemove -= origOldInsert.length - oldOp_toInsert.length;
if (newOp_toRemove < 0) {
newOp_toRemove = 0;
}
oldOp_toRemove += newOp_toRemove;
newOp_toRemove = 0;
}
if (offsetDiff < 0) {
oldOp_offset += offsetDiff;
oldOp_toInsert = newOp_toInsert + oldOp_toInsert;
} else if (oldOp_toInsert.length === offsetDiff) {
oldOp_toInsert = oldOp_toInsert + newOp_toInsert;
} else if (oldOp_toInsert.length > offsetDiff) {
oldOp_toInsert = oldOp_toInsert.substring(0, offsetDiff) + newOp_toInsert + oldOp_toInsert.substring(offsetDiff);
} else {
throw new Error("should never happen\n" + JSON.stringify([ oldOpOrig, newOpOrig ], null, " "));
}
if (oldOp_toInsert === "" && oldOp_toRemove === 0) {
return null;
}
return create(oldOp_offset, oldOp_toRemove, oldOp_toInsert);
};
Operation.shouldMerge = function(oldOp, newOp) {
if (Common.PARANOIA) {
check(oldOp);
check(newOp);
}
if (newOp.offset < oldOp.offset) {
return oldOp.offset <= newOp.offset + newOp.toRemove;
} else {
return newOp.offset <= oldOp.offset + oldOp.toInsert.length;
}
};
Operation.rebase = function(oldOp, newOp) {
if (Common.PARANOIA) {
check(oldOp);
check(newOp);
}
if (newOp.offset < oldOp.offset) {
return newOp;
}
return create(newOp.offset + oldOp.toRemove - oldOp.toInsert.length, newOp.toRemove, newOp.toInsert);
};
Operation.random = function(docLength) {
Common.assert(Common.isUint(docLength));
var offset = Math.floor(Math.random() * 1e8 % docLength) || 0;
var toRemove = Math.floor(Math.random() * 1e8 % (docLength - offset)) || 0;
var toInsert = "";
do {
toInsert = Common.randomASCII(Math.floor(Math.random() * 20));
} while (toRemove === 0 && toInsert === "");
return create(offset, toRemove, toInsert);
};
Object.freeze(module.exports);
},
"sha256/hash.js": function(module, exports, require) {
var Utils = require("./utils.js");
function hash_reset() {
this.result = null;
this.pos = 0;
this.len = 0;
this.asm.reset();
return this;
}
function hash_process(data) {
if (this.result !== null) throw new IllegalStateError("state must be reset before processing new data");
if (Utils.is_string(data)) data = Utils.string_to_bytes(data);
if (Utils.is_buffer(data)) data = new Uint8Array(data);
if (!Utils.is_bytes(data)) throw new TypeError("data isn't of expected type");
var asm = this.asm, heap = this.heap, hpos = this.pos, hlen = this.len, dpos = 0, dlen = data.length, wlen = 0;
while (dlen > 0) {
wlen = Utils._heap_write(heap, hpos + hlen, data, dpos, dlen);
hlen += wlen;
dpos += wlen;
dlen -= wlen;
wlen = asm.process(hpos, hlen);
hpos += wlen;
hlen -= wlen;
if (!hlen) hpos = 0;
}
this.pos = hpos;
this.len = hlen;
return this;
}
function hash_finish() {
if (this.result !== null) throw new IllegalStateError("state must be reset before processing new data");
this.asm.finish(this.pos, this.len, 0);
this.result = new Uint8Array(this.HASH_SIZE);
this.result.set(this.heap.subarray(0, this.HASH_SIZE));
this.pos = 0;
this.len = 0;
return this;
}
module.exports.hash_reset = hash_reset;
module.exports.hash_process = hash_process;
module.exports.hash_finish = hash_finish;
},
"sha256/utils.js": function(module, exports, require) {
var string_to_bytes = module.exports.string_to_bytes = function(str, utf8) {
utf8 = !!utf8;
var len = str.length, bytes = new Uint8Array(utf8 ? 4 * len : len);
for (var i = 0, j = 0; i < len; i++) {
var c = str.charCodeAt(i);
if (utf8 && 55296 <= c && c <= 56319) {
if (++i >= len) throw new Error("Malformed string, low surrogate expected at position " + i);
c = (c ^ 55296) << 10 | 65536 | str.charCodeAt(i) ^ 56320;
} else if (!utf8 && c >>> 8) {
throw new Error("Wide characters are not allowed.");
}
if (!utf8 || c <= 127) {
bytes[j++] = c;
} else if (c <= 2047) {
bytes[j++] = 192 | c >> 6;
bytes[j++] = 128 | c & 63;
} else if (c <= 65535) {
bytes[j++] = 224 | c >> 12;
bytes[j++] = 128 | c >> 6 & 63;
bytes[j++] = 128 | c & 63;
} else {
bytes[j++] = 240 | c >> 18;
bytes[j++] = 128 | c >> 12 & 63;
bytes[j++] = 128 | c >> 6 & 63;
bytes[j++] = 128 | c & 63;
}
}
return bytes.subarray(0, j);
};
module.exports.hex_to_bytes = function(str) {
var len = str.length;
if (len & 1) {
str = "0" + str;
len++;
}
var bytes = new Uint8Array(len >> 1);
for (var i = 0; i < len; i += 2) {
bytes[i >> 1] = parseInt(str.substr(i, 2), 16);
}
return bytes;
};
module.exports.base64_to_bytes = function(str) {
return string_to_bytes(atob(str));
};
var bytes_to_string = module.exports.bytes_to_string = function(bytes, utf8) {
utf8 = !!utf8;
var len = bytes.length, chars = new Array(len);
for (var i = 0, j = 0; i < len; i++) {
var b = bytes[i];
if (!utf8 || b < 128) {
chars[j++] = b;
} else if (b >= 192 && b < 224 && i + 1 < len) {
chars[j++] = (b & 31) << 6 | bytes[++i] & 63;
} else if (b >= 224 && b < 240 && i + 2 < len) {
chars[j++] = (b & 15) << 12 | (bytes[++i] & 63) << 6 | bytes[++i] & 63;
} else if (b >= 240 && b < 248 && i + 3 < len) {
var c = (b & 7) << 18 | (bytes[++i] & 63) << 12 | (bytes[++i] & 63) << 6 | bytes[++i] & 63;
if (c <= 65535) {
chars[j++] = c;
} else {
c ^= 65536;
chars[j++] = 55296 | c >> 10;
chars[j++] = 56320 | c & 1023;
}
} else {
throw new Error("Malformed UTF8 character at byte offset " + i);
}
}
var str = "", bs = 16384;
for (var _i = 0; _i < j; _i += bs) {
str += String.fromCharCode.apply(String, chars.slice(_i, _i + bs <= j ? _i + bs : j));
}
return str;
};
module.exports.bytes_to_hex = function(arr) {
var str = "";
for (var i = 0; i < arr.length; i++) {
var h = (arr[i] & 255).toString(16);
if (h.length < 2) str += "0";
str += h;
}
return str;
};
module.exports.bytes_to_base64 = function(arr) {
return btoa(bytes_to_string(arr));
};
module.exports.pow2_ceil = function(a) {
a -= 1;
a |= a >>> 1;
a |= a >>> 2;
a |= a >>> 4;
a |= a >>> 8;
a |= a >>> 16;
a += 1;
return a;
};
module.exports.is_number = function(a) {
return typeof a === "number";
};
module.exports.is_string = function(a) {
return typeof a === "string";
};
module.exports.is_buffer = function(a) {
return a instanceof ArrayBuffer;
};
module.exports.is_bytes = function(a) {
return a instanceof Uint8Array;
};
module.exports.is_typed_array = function(a) {
return a instanceof Int8Array || a instanceof Uint8Array || a instanceof Int16Array || a instanceof Uint16Array || a instanceof Int32Array || a instanceof Uint32Array || a instanceof Float32Array || a instanceof Float64Array;
};
module.exports._heap_init = function(constructor, options) {
var heap = options.heap, size = heap ? heap.byteLength : options.heapSize || 65536;
if (size & 4095 || size <= 0) throw new Error("heap size must be a positive integer and a multiple of 4096");
heap = heap || new constructor(new ArrayBuffer(size));
return heap;
};
module.exports._heap_write = function(heap, hpos, data, dpos, dlen) {
var hlen = heap.length - hpos, wlen = hlen < dlen ? hlen : dlen;
heap.set(data.subarray(dpos, dpos + wlen), hpos);
return wlen;
};
},
"sha256/sha256.js": function(module, exports, require) {
var Utils = require("./utils.js");
var Hash = require("./hash.js");
var Asm = require("./sha256.asm.js");
var _sha256_block_size = 64, _sha256_hash_size = 32;
function sha256_constructor(options) {
options = options || {};
this.heap = Utils._heap_init(Uint8Array, options);
this.asm = options.asm || Asm.sha256_asm({
Uint8Array
}, null, this.heap.buffer);
this.BLOCK_SIZE = _sha256_block_size;
this.HASH_SIZE = _sha256_hash_size;
this.reset();
}
sha256_constructor.BLOCK_SIZE = _sha256_block_size;
sha256_constructor.HASH_SIZE = _sha256_hash_size;
var sha256_prototype = sha256_constructor.prototype;
sha256_prototype.reset = Hash.hash_reset;
sha256_prototype.process = Hash.hash_process;
sha256_prototype.finish = Hash.hash_finish;
var sha256_instance = null;
function get_sha256_instance() {
if (sha256_instance === null) sha256_instance = new sha256_constructor({
heapSize: 1048576
});
return sha256_instance;
}
module.exports.get_sha256_instance = get_sha256_instance;
module.exports.sha256_constructor = sha256_constructor;
},
"sha256/exports.js": function(module, exports, require) {
var Sha256 = require("./sha256.js");
var Utils = require("./utils.js");
function sha256_bytes(data) {
if (data === undefined) throw new SyntaxError("data required");
return Sha256.get_sha256_instance().reset().process(data).finish().result;
}
function sha256_hex(data) {
var result = sha256_bytes(data);
return Utils.bytes_to_hex(result);
}
function sha256_base64(data) {
var result = sha256_bytes(data);
return Utils.bytes_to_base64(result);
}
Sha256.sha256_constructor.bytes = sha256_bytes;
Sha256.sha256_constructor.hex = sha256_hex;
Sha256.sha256_constructor.base64 = sha256_base64;
module.exports = Sha256.sha256_constructor;
},
"sha256/sha256.asm.js": function(module, exports, require) {
module.exports.sha256_asm = function sha256_asm(stdlib, foreign, buffer) {
"use asm";
var H0 = 0, H1 = 0, H2 = 0, H3 = 0, H4 = 0, H5 = 0, H6 = 0, H7 = 0, TOTAL0 = 0, TOTAL1 = 0;
var I0 = 0, I1 = 0, I2 = 0, I3 = 0, I4 = 0, I5 = 0, I6 = 0, I7 = 0, O0 = 0, O1 = 0, O2 = 0, O3 = 0, O4 = 0, O5 = 0, O6 = 0, O7 = 0;
var HEAP = new stdlib.Uint8Array(buffer);
function _core(w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15) {
w0 = w0 | 0;
w1 = w1 | 0;
w2 = w2 | 0;
w3 = w3 | 0;
w4 = w4 | 0;
w5 = w5 | 0;
w6 = w6 | 0;
w7 = w7 | 0;
w8 = w8 | 0;
w9 = w9 | 0;
w10 = w10 | 0;
w11 = w11 | 0;
w12 = w12 | 0;
w13 = w13 | 0;
w14 = w14 | 0;
w15 = w15 | 0;
var a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, t = 0;
a = H0;
b = H1;
c = H2;
d = H3;
e = H4;
f = H5;
g = H6;
h = H7;
t = w0 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x428a2f98 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
t = w1 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x71374491 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
t = w2 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xb5c0fbcf | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
t = w3 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xe9b5dba5 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
t = w4 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x3956c25b | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
t = w5 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x59f111f1 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
t = w6 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x923f82a4 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
t = w7 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xab1c5ed5 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
t = w8 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xd807aa98 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
t = w9 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x12835b01 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
t = w10 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x243185be | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
t = w11 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x550c7dc3 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
t = w12 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x72be5d74 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
t = w13 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x80deb1fe | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
t = w14 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x9bdc06a7 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
t = w15 + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xc19bf174 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w0 = t = (w1 >>> 7 ^ w1 >>> 18 ^ w1 >>> 3 ^ w1 << 25 ^ w1 << 14) + (w14 >>> 17 ^ w14 >>> 19 ^ w14 >>> 10 ^ w14 << 15 ^ w14 << 13) + w0 + w9 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xe49b69c1 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w1 = t = (w2 >>> 7 ^ w2 >>> 18 ^ w2 >>> 3 ^ w2 << 25 ^ w2 << 14) + (w15 >>> 17 ^ w15 >>> 19 ^ w15 >>> 10 ^ w15 << 15 ^ w15 << 13) + w1 + w10 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xefbe4786 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w2 = t = (w3 >>> 7 ^ w3 >>> 18 ^ w3 >>> 3 ^ w3 << 25 ^ w3 << 14) + (w0 >>> 17 ^ w0 >>> 19 ^ w0 >>> 10 ^ w0 << 15 ^ w0 << 13) + w2 + w11 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x0fc19dc6 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w3 = t = (w4 >>> 7 ^ w4 >>> 18 ^ w4 >>> 3 ^ w4 << 25 ^ w4 << 14) + (w1 >>> 17 ^ w1 >>> 19 ^ w1 >>> 10 ^ w1 << 15 ^ w1 << 13) + w3 + w12 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x240ca1cc | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w4 = t = (w5 >>> 7 ^ w5 >>> 18 ^ w5 >>> 3 ^ w5 << 25 ^ w5 << 14) + (w2 >>> 17 ^ w2 >>> 19 ^ w2 >>> 10 ^ w2 << 15 ^ w2 << 13) + w4 + w13 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x2de92c6f | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w5 = t = (w6 >>> 7 ^ w6 >>> 18 ^ w6 >>> 3 ^ w6 << 25 ^ w6 << 14) + (w3 >>> 17 ^ w3 >>> 19 ^ w3 >>> 10 ^ w3 << 15 ^ w3 << 13) + w5 + w14 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x4a7484aa | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w6 = t = (w7 >>> 7 ^ w7 >>> 18 ^ w7 >>> 3 ^ w7 << 25 ^ w7 << 14) + (w4 >>> 17 ^ w4 >>> 19 ^ w4 >>> 10 ^ w4 << 15 ^ w4 << 13) + w6 + w15 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x5cb0a9dc | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w7 = t = (w8 >>> 7 ^ w8 >>> 18 ^ w8 >>> 3 ^ w8 << 25 ^ w8 << 14) + (w5 >>> 17 ^ w5 >>> 19 ^ w5 >>> 10 ^ w5 << 15 ^ w5 << 13) + w7 + w0 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x76f988da | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w8 = t = (w9 >>> 7 ^ w9 >>> 18 ^ w9 >>> 3 ^ w9 << 25 ^ w9 << 14) + (w6 >>> 17 ^ w6 >>> 19 ^ w6 >>> 10 ^ w6 << 15 ^ w6 << 13) + w8 + w1 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x983e5152 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w9 = t = (w10 >>> 7 ^ w10 >>> 18 ^ w10 >>> 3 ^ w10 << 25 ^ w10 << 14) + (w7 >>> 17 ^ w7 >>> 19 ^ w7 >>> 10 ^ w7 << 15 ^ w7 << 13) + w9 + w2 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xa831c66d | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w10 = t = (w11 >>> 7 ^ w11 >>> 18 ^ w11 >>> 3 ^ w11 << 25 ^ w11 << 14) + (w8 >>> 17 ^ w8 >>> 19 ^ w8 >>> 10 ^ w8 << 15 ^ w8 << 13) + w10 + w3 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xb00327c8 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w11 = t = (w12 >>> 7 ^ w12 >>> 18 ^ w12 >>> 3 ^ w12 << 25 ^ w12 << 14) + (w9 >>> 17 ^ w9 >>> 19 ^ w9 >>> 10 ^ w9 << 15 ^ w9 << 13) + w11 + w4 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xbf597fc7 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w12 = t = (w13 >>> 7 ^ w13 >>> 18 ^ w13 >>> 3 ^ w13 << 25 ^ w13 << 14) + (w10 >>> 17 ^ w10 >>> 19 ^ w10 >>> 10 ^ w10 << 15 ^ w10 << 13) + w12 + w5 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xc6e00bf3 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w13 = t = (w14 >>> 7 ^ w14 >>> 18 ^ w14 >>> 3 ^ w14 << 25 ^ w14 << 14) + (w11 >>> 17 ^ w11 >>> 19 ^ w11 >>> 10 ^ w11 << 15 ^ w11 << 13) + w13 + w6 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xd5a79147 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w14 = t = (w15 >>> 7 ^ w15 >>> 18 ^ w15 >>> 3 ^ w15 << 25 ^ w15 << 14) + (w12 >>> 17 ^ w12 >>> 19 ^ w12 >>> 10 ^ w12 << 15 ^ w12 << 13) + w14 + w7 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x06ca6351 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w15 = t = (w0 >>> 7 ^ w0 >>> 18 ^ w0 >>> 3 ^ w0 << 25 ^ w0 << 14) + (w13 >>> 17 ^ w13 >>> 19 ^ w13 >>> 10 ^ w13 << 15 ^ w13 << 13) + w15 + w8 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x14292967 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w0 = t = (w1 >>> 7 ^ w1 >>> 18 ^ w1 >>> 3 ^ w1 << 25 ^ w1 << 14) + (w14 >>> 17 ^ w14 >>> 19 ^ w14 >>> 10 ^ w14 << 15 ^ w14 << 13) + w0 + w9 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x27b70a85 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w1 = t = (w2 >>> 7 ^ w2 >>> 18 ^ w2 >>> 3 ^ w2 << 25 ^ w2 << 14) + (w15 >>> 17 ^ w15 >>> 19 ^ w15 >>> 10 ^ w15 << 15 ^ w15 << 13) + w1 + w10 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x2e1b2138 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w2 = t = (w3 >>> 7 ^ w3 >>> 18 ^ w3 >>> 3 ^ w3 << 25 ^ w3 << 14) + (w0 >>> 17 ^ w0 >>> 19 ^ w0 >>> 10 ^ w0 << 15 ^ w0 << 13) + w2 + w11 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x4d2c6dfc | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w3 = t = (w4 >>> 7 ^ w4 >>> 18 ^ w4 >>> 3 ^ w4 << 25 ^ w4 << 14) + (w1 >>> 17 ^ w1 >>> 19 ^ w1 >>> 10 ^ w1 << 15 ^ w1 << 13) + w3 + w12 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x53380d13 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w4 = t = (w5 >>> 7 ^ w5 >>> 18 ^ w5 >>> 3 ^ w5 << 25 ^ w5 << 14) + (w2 >>> 17 ^ w2 >>> 19 ^ w2 >>> 10 ^ w2 << 15 ^ w2 << 13) + w4 + w13 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x650a7354 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w5 = t = (w6 >>> 7 ^ w6 >>> 18 ^ w6 >>> 3 ^ w6 << 25 ^ w6 << 14) + (w3 >>> 17 ^ w3 >>> 19 ^ w3 >>> 10 ^ w3 << 15 ^ w3 << 13) + w5 + w14 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x766a0abb | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w6 = t = (w7 >>> 7 ^ w7 >>> 18 ^ w7 >>> 3 ^ w7 << 25 ^ w7 << 14) + (w4 >>> 17 ^ w4 >>> 19 ^ w4 >>> 10 ^ w4 << 15 ^ w4 << 13) + w6 + w15 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x81c2c92e | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w7 = t = (w8 >>> 7 ^ w8 >>> 18 ^ w8 >>> 3 ^ w8 << 25 ^ w8 << 14) + (w5 >>> 17 ^ w5 >>> 19 ^ w5 >>> 10 ^ w5 << 15 ^ w5 << 13) + w7 + w0 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x92722c85 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w8 = t = (w9 >>> 7 ^ w9 >>> 18 ^ w9 >>> 3 ^ w9 << 25 ^ w9 << 14) + (w6 >>> 17 ^ w6 >>> 19 ^ w6 >>> 10 ^ w6 << 15 ^ w6 << 13) + w8 + w1 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xa2bfe8a1 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w9 = t = (w10 >>> 7 ^ w10 >>> 18 ^ w10 >>> 3 ^ w10 << 25 ^ w10 << 14) + (w7 >>> 17 ^ w7 >>> 19 ^ w7 >>> 10 ^ w7 << 15 ^ w7 << 13) + w9 + w2 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xa81a664b | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w10 = t = (w11 >>> 7 ^ w11 >>> 18 ^ w11 >>> 3 ^ w11 << 25 ^ w11 << 14) + (w8 >>> 17 ^ w8 >>> 19 ^ w8 >>> 10 ^ w8 << 15 ^ w8 << 13) + w10 + w3 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xc24b8b70 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w11 = t = (w12 >>> 7 ^ w12 >>> 18 ^ w12 >>> 3 ^ w12 << 25 ^ w12 << 14) + (w9 >>> 17 ^ w9 >>> 19 ^ w9 >>> 10 ^ w9 << 15 ^ w9 << 13) + w11 + w4 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xc76c51a3 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w12 = t = (w13 >>> 7 ^ w13 >>> 18 ^ w13 >>> 3 ^ w13 << 25 ^ w13 << 14) + (w10 >>> 17 ^ w10 >>> 19 ^ w10 >>> 10 ^ w10 << 15 ^ w10 << 13) + w12 + w5 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xd192e819 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w13 = t = (w14 >>> 7 ^ w14 >>> 18 ^ w14 >>> 3 ^ w14 << 25 ^ w14 << 14) + (w11 >>> 17 ^ w11 >>> 19 ^ w11 >>> 10 ^ w11 << 15 ^ w11 << 13) + w13 + w6 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xd6990624 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w14 = t = (w15 >>> 7 ^ w15 >>> 18 ^ w15 >>> 3 ^ w15 << 25 ^ w15 << 14) + (w12 >>> 17 ^ w12 >>> 19 ^ w12 >>> 10 ^ w12 << 15 ^ w12 << 13) + w14 + w7 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xf40e3585 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w15 = t = (w0 >>> 7 ^ w0 >>> 18 ^ w0 >>> 3 ^ w0 << 25 ^ w0 << 14) + (w13 >>> 17 ^ w13 >>> 19 ^ w13 >>> 10 ^ w13 << 15 ^ w13 << 13) + w15 + w8 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x106aa070 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w0 = t = (w1 >>> 7 ^ w1 >>> 18 ^ w1 >>> 3 ^ w1 << 25 ^ w1 << 14) + (w14 >>> 17 ^ w14 >>> 19 ^ w14 >>> 10 ^ w14 << 15 ^ w14 << 13) + w0 + w9 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x19a4c116 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w1 = t = (w2 >>> 7 ^ w2 >>> 18 ^ w2 >>> 3 ^ w2 << 25 ^ w2 << 14) + (w15 >>> 17 ^ w15 >>> 19 ^ w15 >>> 10 ^ w15 << 15 ^ w15 << 13) + w1 + w10 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x1e376c08 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w2 = t = (w3 >>> 7 ^ w3 >>> 18 ^ w3 >>> 3 ^ w3 << 25 ^ w3 << 14) + (w0 >>> 17 ^ w0 >>> 19 ^ w0 >>> 10 ^ w0 << 15 ^ w0 << 13) + w2 + w11 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x2748774c | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w3 = t = (w4 >>> 7 ^ w4 >>> 18 ^ w4 >>> 3 ^ w4 << 25 ^ w4 << 14) + (w1 >>> 17 ^ w1 >>> 19 ^ w1 >>> 10 ^ w1 << 15 ^ w1 << 13) + w3 + w12 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x34b0bcb5 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w4 = t = (w5 >>> 7 ^ w5 >>> 18 ^ w5 >>> 3 ^ w5 << 25 ^ w5 << 14) + (w2 >>> 17 ^ w2 >>> 19 ^ w2 >>> 10 ^ w2 << 15 ^ w2 << 13) + w4 + w13 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x391c0cb3 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w5 = t = (w6 >>> 7 ^ w6 >>> 18 ^ w6 >>> 3 ^ w6 << 25 ^ w6 << 14) + (w3 >>> 17 ^ w3 >>> 19 ^ w3 >>> 10 ^ w3 << 15 ^ w3 << 13) + w5 + w14 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x4ed8aa4a | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w6 = t = (w7 >>> 7 ^ w7 >>> 18 ^ w7 >>> 3 ^ w7 << 25 ^ w7 << 14) + (w4 >>> 17 ^ w4 >>> 19 ^ w4 >>> 10 ^ w4 << 15 ^ w4 << 13) + w6 + w15 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x5b9cca4f | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w7 = t = (w8 >>> 7 ^ w8 >>> 18 ^ w8 >>> 3 ^ w8 << 25 ^ w8 << 14) + (w5 >>> 17 ^ w5 >>> 19 ^ w5 >>> 10 ^ w5 << 15 ^ w5 << 13) + w7 + w0 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x682e6ff3 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w8 = t = (w9 >>> 7 ^ w9 >>> 18 ^ w9 >>> 3 ^ w9 << 25 ^ w9 << 14) + (w6 >>> 17 ^ w6 >>> 19 ^ w6 >>> 10 ^ w6 << 15 ^ w6 << 13) + w8 + w1 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x748f82ee | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w9 = t = (w10 >>> 7 ^ w10 >>> 18 ^ w10 >>> 3 ^ w10 << 25 ^ w10 << 14) + (w7 >>> 17 ^ w7 >>> 19 ^ w7 >>> 10 ^ w7 << 15 ^ w7 << 13) + w9 + w2 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x78a5636f | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w10 = t = (w11 >>> 7 ^ w11 >>> 18 ^ w11 >>> 3 ^ w11 << 25 ^ w11 << 14) + (w8 >>> 17 ^ w8 >>> 19 ^ w8 >>> 10 ^ w8 << 15 ^ w8 << 13) + w10 + w3 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x84c87814 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w11 = t = (w12 >>> 7 ^ w12 >>> 18 ^ w12 >>> 3 ^ w12 << 25 ^ w12 << 14) + (w9 >>> 17 ^ w9 >>> 19 ^ w9 >>> 10 ^ w9 << 15 ^ w9 << 13) + w11 + w4 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x8cc70208 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w12 = t = (w13 >>> 7 ^ w13 >>> 18 ^ w13 >>> 3 ^ w13 << 25 ^ w13 << 14) + (w10 >>> 17 ^ w10 >>> 19 ^ w10 >>> 10 ^ w10 << 15 ^ w10 << 13) + w12 + w5 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0x90befffa | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w13 = t = (w14 >>> 7 ^ w14 >>> 18 ^ w14 >>> 3 ^ w14 << 25 ^ w14 << 14) + (w11 >>> 17 ^ w11 >>> 19 ^ w11 >>> 10 ^ w11 << 15 ^ w11 << 13) + w13 + w6 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xa4506ceb | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w14 = t = (w15 >>> 7 ^ w15 >>> 18 ^ w15 >>> 3 ^ w15 << 25 ^ w15 << 14) + (w12 >>> 17 ^ w12 >>> 19 ^ w12 >>> 10 ^ w12 << 15 ^ w12 << 13) + w14 + w7 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xbef9a3f7 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
w15 = t = (w0 >>> 7 ^ w0 >>> 18 ^ w0 >>> 3 ^ w0 << 25 ^ w0 << 14) + (w13 >>> 17 ^ w13 >>> 19 ^ w13 >>> 10 ^ w13 << 15 ^ w13 << 13) + w15 + w8 | 0;
t = t + h + (e >>> 6 ^ e >>> 11 ^ e >>> 25 ^ e << 26 ^ e << 21 ^ e << 7) + (g ^ e & (f ^ g)) + 0xc67178f2 | 0;
h = g;
g = f;
f = e;
e = d + t | 0;
d = c;
c = b;
b = a;
a = t + (b & c ^ d & (b ^ c)) + (b >>> 2 ^ b >>> 13 ^ b >>> 22 ^ b << 30 ^ b << 19 ^ b << 10) | 0;
H0 = H0 + a | 0;
H1 = H1 + b | 0;
H2 = H2 + c | 0;
H3 = H3 + d | 0;
H4 = H4 + e | 0;
H5 = H5 + f | 0;
H6 = H6 + g | 0;
H7 = H7 + h | 0;
}
function _core_heap(offset) {
offset = offset | 0;
_core(HEAP[offset | 0] << 24 | HEAP[offset | 1] << 16 | HEAP[offset | 2] << 8 | HEAP[offset | 3], HEAP[offset | 4] << 24 | HEAP[offset | 5] << 16 | HEAP[offset | 6] << 8 | HEAP[offset | 7], HEAP[offset | 8] << 24 | HEAP[offset | 9] << 16 | HEAP[offset | 10] << 8 | HEAP[offset | 11], HEAP[offset | 12] << 24 | HEAP[offset | 13] << 16 | HEAP[offset | 14] << 8 | HEAP[offset | 15], HEAP[offset | 16] << 24 | HEAP[offset | 17] << 16 | HEAP[offset | 18] << 8 | HEAP[offset | 19], HEAP[offset | 20] << 24 | HEAP[offset | 21] << 16 | HEAP[offset | 22] << 8 | HEAP[offset | 23], HEAP[offset | 24] << 24 | HEAP[offset | 25] << 16 | HEAP[offset | 26] << 8 | HEAP[offset | 27], HEAP[offset | 28] << 24 | HEAP[offset | 29] << 16 | HEAP[offset | 30] << 8 | HEAP[offset | 31], HEAP[offset | 32] << 24 | HEAP[offset | 33] << 16 | HEAP[offset | 34] << 8 | HEAP[offset | 35], HEAP[offset | 36] << 24 | HEAP[offset | 37] << 16 | HEAP[offset | 38] << 8 | HEAP[offset | 39], HEAP[offset | 40] << 24 | HEAP[offset | 41] << 16 | HEAP[offset | 42] << 8 | HEAP[offset | 43], HEAP[offset | 44] << 24 | HEAP[offset | 45] << 16 | HEAP[offset | 46] << 8 | HEAP[offset | 47], HEAP[offset | 48] << 24 | HEAP[offset | 49] << 16 | HEAP[offset | 50] << 8 | HEAP[offset | 51], HEAP[offset | 52] << 24 | HEAP[offset | 53] << 16 | HEAP[offset | 54] << 8 | HEAP[offset | 55], HEAP[offset | 56] << 24 | HEAP[offset | 57] << 16 | HEAP[offset | 58] << 8 | HEAP[offset | 59], HEAP[offset | 60] << 24 | HEAP[offset | 61] << 16 | HEAP[offset | 62] << 8 | HEAP[offset | 63]);
}
function _state_to_heap(output) {
output = output | 0;
HEAP[output | 0] = H0 >>> 24;
HEAP[output | 1] = H0 >>> 16 & 255;
HEAP[output | 2] = H0 >>> 8 & 255;
HEAP[output | 3] = H0 & 255;
HEAP[output | 4] = H1 >>> 24;
HEAP[output | 5] = H1 >>> 16 & 255;
HEAP[output | 6] = H1 >>> 8 & 255;
HEAP[output | 7] = H1 & 255;
HEAP[output | 8] = H2 >>> 24;
HEAP[output | 9] = H2 >>> 16 & 255;
HEAP[output | 10] = H2 >>> 8 & 255;
HEAP[output | 11] = H2 & 255;
HEAP[output | 12] = H3 >>> 24;
HEAP[output | 13] = H3 >>> 16 & 255;
HEAP[output | 14] = H3 >>> 8 & 255;
HEAP[output | 15] = H3 & 255;
HEAP[output | 16] = H4 >>> 24;
HEAP[output | 17] = H4 >>> 16 & 255;
HEAP[output | 18] = H4 >>> 8 & 255;
HEAP[output | 19] = H4 & 255;
HEAP[output | 20] = H5 >>> 24;
HEAP[output | 21] = H5 >>> 16 & 255;
HEAP[output | 22] = H5 >>> 8 & 255;
HEAP[output | 23] = H5 & 255;
HEAP[output | 24] = H6 >>> 24;
HEAP[output | 25] = H6 >>> 16 & 255;
HEAP[output | 26] = H6 >>> 8 & 255;
HEAP[output | 27] = H6 & 255;
HEAP[output | 28] = H7 >>> 24;
HEAP[output | 29] = H7 >>> 16 & 255;
HEAP[output | 30] = H7 >>> 8 & 255;
HEAP[output | 31] = H7 & 255;
}
function reset() {
H0 = 0x6a09e667;
H1 = 0xbb67ae85;
H2 = 0x3c6ef372;
H3 = 0xa54ff53a;
H4 = 0x510e527f;
H5 = 0x9b05688c;
H6 = 0x1f83d9ab;
H7 = 0x5be0cd19;
TOTAL0 = TOTAL1 = 0;
}
function init(h0, h1, h2, h3, h4, h5, h6, h7, total0, total1) {
h0 = h0 | 0;
h1 = h1 | 0;
h2 = h2 | 0;
h3 = h3 | 0;
h4 = h4 | 0;
h5 = h5 | 0;
h6 = h6 | 0;
h7 = h7 | 0;
total0 = total0 | 0;
total1 = total1 | 0;
H0 = h0;
H1 = h1;
H2 = h2;
H3 = h3;
H4 = h4;
H5 = h5;
H6 = h6;
H7 = h7;
TOTAL0 = total0;
TOTAL1 = total1;
}
function process(offset, length) {
offset = offset | 0;
length = length | 0;
var hashed = 0;
if (offset & 63) return -1;
while ((length | 0) >= 64) {
_core_heap(offset);
offset = offset + 64 | 0;
length = length - 64 | 0;
hashed = hashed + 64 | 0;
}
TOTAL0 = TOTAL0 + hashed | 0;
if (TOTAL0 >>> 0 < hashed >>> 0) TOTAL1 = TOTAL1 + 1 | 0;
return hashed | 0;
}
function finish(offset, length, output) {
offset = offset | 0;
length = length | 0;
output = output | 0;
var hashed = 0, i = 0;
if (offset & 63) return -1;
if (~output) if (output & 31) return -1;
if ((length | 0) >= 64) {
hashed = process(offset, length) | 0;
if ((hashed | 0) == -1) return -1;
offset = offset + hashed | 0;
length = length - hashed | 0;
}
hashed = hashed + length | 0;
TOTAL0 = TOTAL0 + length | 0;
if (TOTAL0 >>> 0 < length >>> 0) TOTAL1 = TOTAL1 + 1 | 0;
HEAP[offset | length] = 0x80;
if ((length | 0) >= 56) {
for (i = length + 1 | 0; (i | 0) < 64; i = i + 1 | 0) HEAP[offset | i] = 0x00;
_core_heap(offset);
length = 0;
HEAP[offset | 0] = 0;
}
for (i = length + 1 | 0; (i | 0) < 59; i = i + 1 | 0) HEAP[offset | i] = 0;
HEAP[offset | 56] = TOTAL1 >>> 21 & 255;
HEAP[offset | 57] = TOTAL1 >>> 13 & 255;
HEAP[offset | 58] = TOTAL1 >>> 5 & 255;
HEAP[offset | 59] = TOTAL1 << 3 & 255 | TOTAL0 >>> 29;
HEAP[offset | 60] = TOTAL0 >>> 21 & 255;
HEAP[offset | 61] = TOTAL0 >>> 13 & 255;
HEAP[offset | 62] = TOTAL0 >>> 5 & 255;
HEAP[offset | 63] = TOTAL0 << 3 & 255;
_core_heap(offset);
if (~output) _state_to_heap(output);
return hashed | 0;
}
function hmac_reset() {
H0 = I0;
H1 = I1;
H2 = I2;
H3 = I3;
H4 = I4;
H5 = I5;
H6 = I6;
H7 = I7;
TOTAL0 = 64;
TOTAL1 = 0;
}
function _hmac_opad() {
H0 = O0;
H1 = O1;
H2 = O2;
H3 = O3;
H4 = O4;
H5 = O5;
H6 = O6;
H7 = O7;
TOTAL0 = 64;
TOTAL1 = 0;
}
function hmac_init(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15) {
p0 = p0 | 0;
p1 = p1 | 0;
p2 = p2 | 0;
p3 = p3 | 0;
p4 = p4 | 0;
p5 = p5 | 0;
p6 = p6 | 0;
p7 = p7 | 0;
p8 = p8 | 0;
p9 = p9 | 0;
p10 = p10 | 0;
p11 = p11 | 0;
p12 = p12 | 0;
p13 = p13 | 0;
p14 = p14 | 0;
p15 = p15 | 0;
reset();
_core(p0 ^ 0x5c5c5c5c, p1 ^ 0x5c5c5c5c, p2 ^ 0x5c5c5c5c, p3 ^ 0x5c5c5c5c, p4 ^ 0x5c5c5c5c, p5 ^ 0x5c5c5c5c, p6 ^ 0x5c5c5c5c, p7 ^ 0x5c5c5c5c, p8 ^ 0x5c5c5c5c, p9 ^ 0x5c5c5c5c, p10 ^ 0x5c5c5c5c, p11 ^ 0x5c5c5c5c, p12 ^ 0x5c5c5c5c, p13 ^ 0x5c5c5c5c, p14 ^ 0x5c5c5c5c, p15 ^ 0x5c5c5c5c);
O0 = H0;
O1 = H1;
O2 = H2;
O3 = H3;
O4 = H4;
O5 = H5;
O6 = H6;
O7 = H7;
reset();
_core(p0 ^ 0x36363636, p1 ^ 0x36363636, p2 ^ 0x36363636, p3 ^ 0x36363636, p4 ^ 0x36363636, p5 ^ 0x36363636, p6 ^ 0x36363636, p7 ^ 0x36363636, p8 ^ 0x36363636, p9 ^ 0x36363636, p10 ^ 0x36363636, p11 ^ 0x36363636, p12 ^ 0x36363636, p13 ^ 0x36363636, p14 ^ 0x36363636, p15 ^ 0x36363636);
I0 = H0;
I1 = H1;
I2 = H2;
I3 = H3;
I4 = H4;
I5 = H5;
I6 = H6;
I7 = H7;
TOTAL0 = 64;
TOTAL1 = 0;
}
function hmac_finish(offset, length, output) {
offset = offset | 0;
length = length | 0;
output = output | 0;
var t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, hashed = 0;
if (offset & 63) return -1;
if (~output) if (output & 31) return -1;
hashed = finish(offset, length, -1) | 0;
t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4, t5 = H5, t6 = H6, t7 = H7;
_hmac_opad();
_core(t0, t1, t2, t3, t4, t5, t6, t7, 0x80000000, 0, 0, 0, 0, 0, 0, 768);
if (~output) _state_to_heap(output);
return hashed | 0;
}
function pbkdf2_generate_block(offset, length, block, count, output) {
offset = offset | 0;
length = length | 0;
block = block | 0;
count = count | 0;
output = output | 0;
var h0 = 0, h1 = 0, h2 = 0, h3 = 0, h4 = 0, h5 = 0, h6 = 0, h7 = 0, t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0;
if (offset & 63) return -1;
if (~output) if (output & 31) return -1;
HEAP[offset + length | 0] = block >>> 24;
HEAP[offset + length + 1 | 0] = block >>> 16 & 255;
HEAP[offset + length + 2 | 0] = block >>> 8 & 255;
HEAP[offset + length + 3 | 0] = block & 255;
hmac_finish(offset, length + 4 | 0, -1) | 0;
h0 = t0 = H0, h1 = t1 = H1, h2 = t2 = H2, h3 = t3 = H3, h4 = t4 = H4, h5 = t5 = H5,
h6 = t6 = H6, h7 = t7 = H7;
count = count - 1 | 0;
while ((count | 0) > 0) {
hmac_reset();
_core(t0, t1, t2, t3, t4, t5, t6, t7, 0x80000000, 0, 0, 0, 0, 0, 0, 768);
t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4, t5 = H5, t6 = H6, t7 = H7;
_hmac_opad();
_core(t0, t1, t2, t3, t4, t5, t6, t7, 0x80000000, 0, 0, 0, 0, 0, 0, 768);
t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4, t5 = H5, t6 = H6, t7 = H7;
h0 = h0 ^ H0;
h1 = h1 ^ H1;
h2 = h2 ^ H2;
h3 = h3 ^ H3;
h4 = h4 ^ H4;
h5 = h5 ^ H5;
h6 = h6 ^ H6;
h7 = h7 ^ H7;
count = count - 1 | 0;
}
H0 = h0;
H1 = h1;
H2 = h2;
H3 = h3;
H4 = h4;
H5 = h5;
H6 = h6;
H7 = h7;
if (~output) _state_to_heap(output);
return 0;
}
return {
reset,
init,
process,
finish,
hmac_reset,
hmac_init,
hmac_finish,
pbkdf2_generate_block
};
};
},
"transform/TextTransformer.js": function(module, exports, require) {
var Operation = require("../Operation");
var Common = require("../Common");
var transformOp0 = function(toTransform, transformBy) {
if (toTransform.offset > transformBy.offset) {
if (toTransform.offset > transformBy.offset + transformBy.toRemove) {
return Operation.create(toTransform.offset - transformBy.toRemove + transformBy.toInsert.length, toTransform.toRemove, toTransform.toInsert);
}
var newToRemove = toTransform.toRemove - (transformBy.offset + transformBy.toRemove - toTransform.offset);
if (newToRemove < 0) {
newToRemove = 0;
}
if (newToRemove === 0 && toTransform.toInsert.length === 0) {
return null;
}
return Operation.create(transformBy.offset + transformBy.toInsert.length, newToRemove, toTransform.toInsert);
}
if (toTransform.offset + toTransform.toRemove < transformBy.offset) {
return toTransform;
}
var _newToRemove = transformBy.offset - toTransform.offset;
if (_newToRemove === 0 && toTransform.toInsert.length === 0) {
return null;
}
return Operation.create(toTransform.offset, _newToRemove, toTransform.toInsert);
};
var transformOp = function(toTransform, transformBy) {
if (Common.PARANOIA) {
Operation.check(toTransform);
Operation.check(transformBy);
}
var result = transformOp0(toTransform, transformBy);
if (Common.PARANOIA && result) {
Operation.check(result);
}
return result;
};
module.exports = function(opsToTransform, opsTransformBy, doc) {
var resultOfTransformBy = doc;
var i;
for (i = opsTransformBy.length - 1; i >= 0; i--) {
resultOfTransformBy = Operation.apply(opsTransformBy[i], resultOfTransformBy);
}
var out = [];
for (i = opsToTransform.length - 1; i >= 0; i--) {
var tti = opsToTransform[i];
for (var j = opsTransformBy.length - 1; j >= 0; j--) {
try {
tti = transformOp(tti, opsTransformBy[j]);
} catch (e) {
console.error("The pluggable transform function threw an error, " + "failing operational transformation");
console.error(e.stack);
return [];
}
if (!tti) {
break;
}
}
if (tti) {
if (Common.PARANOIA) {
Operation.check(tti, resultOfTransformBy.length);
}
out.unshift(tti);
}
}
return out;
};
},
"transform/NaiveJSONTransformer.js": function(module, exports, require) {
var TextTransformer = require("./TextTransformer");
var Operation = require("../Operation");
var Common = require("../Common");
module.exports = function(opsToTransform, opsTransformBy, text) {
var DEBUG = Common.global.REALTIME_DEBUG = Common.global.REALTIME_DEBUG || {};
var resultOps, text2, text3;
try {
resultOps = TextTransformer(opsToTransform, opsTransformBy, text);
text2 = Operation.applyMulti(opsTransformBy, text);
text3 = Operation.applyMulti(resultOps, text2);
try {
JSON.parse(text3);
return resultOps;
} catch (e) {
console.error(e);
DEBUG.ot_parseError = {
type: "resultParseError",
resultOps,
toTransform: opsToTransform,
transformBy: opsTransformBy,
text1: text,
text2,
text3,
error: e
};
console.log("Debugging info available at `window.REALTIME_DEBUG.ot_parseError`");
}
} catch (x) {
console.error(x);
DEBUG.ot_applyError = {
type: "resultParseError",
resultOps,
toTransform: opsToTransform,
transformBy: opsTransformBy,
text1: text,
text2,
text3,
error: x
};
console.log("Debugging info available at `window.REALTIME_DEBUG.ot_applyError`");
}
return [];
};
},
"transform/SmartJSONTransformer.js": function(module, exports, require) {
var Sortify = require("json.sortify");
var Diff = require("../Diff");
var Operation = require("../Operation");
var TextTransformer = require("./TextTransformer");
var isArray = function(obj) {
return Object.prototype.toString.call(obj) === "[object Array]";
};
var type = function(dat) {
return dat === null ? "null" : isArray(dat) ? "array" : typeof dat;
};
var find = function(map, path) {
var l = path.length;
for (var i = 0; i < l; i++) {
if (typeof map[path[i]] === "undefined") {
return;
}
map = map[path[i]];
}
return map;
};
var clone = function(val) {
return JSON.parse(JSON.stringify(val));
};
var deepEqual = function(A, B) {
var t_A = type(A);
var t_B = type(B);
if (t_A !== t_B) {
return false;
}
if (t_A === "object") {
var k_A = Object.keys(A);
var k_B = Object.keys(B);
return k_A.length === k_B.length && !k_A.some((function(a) {
return !deepEqual(A[a], B[a]);
})) && !k_B.some((function(b) {
return !(b in A);
}));
} else if (t_A === "array") {
return A.length === B.length && !A.some((function(a, i) {
return !deepEqual(a, B[i]);
}));
} else {
return A === B;
}
};
var operation = function(type, path, value, prev, other) {
if (type === "replace") {
return {
type: "replace",
path,
value,
prev
};
} else if (type === "splice") {
if (typeof prev !== "number") {
throw new Error;
}
if (typeof other !== "number") {
throw new Error;
}
return {
type: "splice",
path,
value,
offset: prev,
removals: other
};
} else if (type !== "remove") {
throw new Error("expected a removal");
}
return {
type: "remove",
path,
value
};
};
var replace = function(ops, path, to, from) {
ops.push(operation("replace", path, to, from));
};
var remove = function(ops, path, val) {
ops.push(operation("remove", path, val));
};
var splice = function(ops, path, value, offset, removals) {
ops.push(operation("splice", path, value, offset, removals));
};
var pathOverlaps = function(A, B) {
return !A.some((function(a, i) {
return a !== B[i];
}));
};
var CASES = function() {
var types = [ "replace", "remove", "splice" ];
var matrix = {};
var i = 1;
types.forEach((function(a) {
matrix[a] = {};
return types.forEach((function(b) {
matrix[a][b] = i++;
}));
}));
return matrix;
}();
var resolve = function(A, B, arbiter) {
if (!(type(A) === "array" && type(B) === "array")) {
throw new Error("[resolve] expected two arrays");
}
B = B.filter((function(b) {
if (A.some((function(a) {
if (a.type === "remove") {
if (pathOverlaps(a.path, b.path)) {
if (b.path.length - a.path.length > 1) {
return true;
}
}
}
}))) {
return false;
}
if (b.type === "splice" && A.some((function(a) {
if (a.type === "splice" && pathOverlaps(a.path, b.path)) {
if (a.path.length - b.path.length < 0) {
if (!a.removals) {
return;
}
var start = a.offset;
var end = a.offset + a.removals;
for (;start < end; start++) {
if (start === b.path[a.path.length]) {
return true;
}
}
}
}
}))) {
return false;
}
if (!A.some((function(a) {
return b.type === "remove" && deepEqual(a.path, b.path);
}))) {
return true;
}
})).filter((function(b) {
return !A.some((function(a) {
if (b.type === "replace" && a.type === "replace") {
if (deepEqual(a.path, b.path)) {
if (typeof a.value === "string" && typeof b.value === "string") {
if (arbiter && a.prev === b.prev && a.value !== b.value) {
return arbiter(a, b, CASES.replace.replace);
}
return true;
}
return true;
}
}
}));
})).map((function(b) {
A.forEach((function(a) {
if (a.type === "splice") {
if (deepEqual(a.path, b.path)) {
if (b.type === "splice") {
if (b.offset > a.offset + b.removals) {
b.offset += a.value.length - a.removals;
return;
}
if (b.offset < a.offset) {
b.removals = Math.max(a.offset - b.offset, 0);
return;
}
b.removals = Math.max(b.removals - (b.offset + a.removals - b.offset), 0);
b.offset += a.value.length - a.removals;
}
return;
}
if (pathOverlaps(a.path, b.path)) {
var pos = a.path.length;
if (typeof b.path[pos] === "number" && a.offset <= b.path[pos]) {
b.path[pos] += a.value.length - a.removals;
}
}
}
}));
return b;
}));
return B;
};
var objects = function(A, B, path, ops) {
var Akeys = Object.keys(A);
var Bkeys = Object.keys(B);
Bkeys.forEach((function(b) {
var t_b = type(B[b]);
var old = A[b];
var nextPath = path.concat(b);
if (Akeys.indexOf(b) === -1) {
if (t_b === "undefined") {
throw new Error("undefined type has key. this shouldn't happen?");
}
if (old) {
throw new Error("no such key existed in b, so 'old' should be falsey");
}
replace(ops, nextPath, B[b], old);
return;
}
var t_a = type(old);
if (t_a !== t_b) {
console.log("type changed from [%s] to [%s]", t_a, t_b);
if (t_b === "undefined") {
throw new Error("first pass should never reveal undefined keys");
}
replace(ops, nextPath, B[b], old);
return;
}
if (t_a === "object") {
objects(A[b], B[b], nextPath, ops);
} else if (t_a === "array") {
arrays(A[b], B[b], nextPath, ops);
} else if (A[b] !== B[b]) {
replace(ops, nextPath, B[b], old);
}
}));
Akeys.forEach((function(a) {
if (Bkeys.indexOf(a) === -1 || type(B[a]) === "undefined") {
remove(ops, path.concat(a), A[a]);
}
}));
};
var arrayShallowEquality = function(A, B) {
if (A.length !== B.length) {
return false;
}
for (var i = 0; i < A.length; i++) {
if (type(A[i]) !== type(B[i])) {
return false;
}
}
return true;
};
var arrays = function(A_orig, B, path, ops) {
var A = A_orig.slice(0);
if (A.length === 0) {
splice(ops, path, B, 0, 0);
} else if (arrayShallowEquality(A, B)) {
A.forEach((function(a, i) {
var b = B[i];
if (b === a) {
return;
}
var old = a;
var nextPath = path.concat(i);
var t_a = type(a);
switch (t_a) {
case "undefined":
throw new Error("existing key had type `undefined`. this should never happen");
case "object":
objects(a, b, nextPath, ops);
break;
case "array":
arrays(a, b, nextPath, ops);
break;
default:
replace(ops, nextPath, b, old);
}
}));
} else {
var commonStart = 0;
var commonEnd = 0;
while (commonStart < A.length && deepEqual(A[commonStart], B[commonStart])) {
commonStart++;
}
while (deepEqual(A[A.length - 1 - commonEnd], B[B.length - 1 - commonEnd]) && commonEnd + commonStart < A.length && commonEnd + commonStart < B.length) {
commonEnd++;
}
var toRemove = A.length - commonStart - commonEnd;
var toInsert = [];
if (B.length !== commonStart + commonEnd) {
toInsert = B.slice(commonStart, B.length - commonEnd);
}
splice(ops, path, toInsert, commonStart, toRemove);
}
};
var diff = function(A, B) {
var ops = [];
var t_A = type(A);
var t_B = type(B);
if (t_A !== t_B) {
throw new Error("Can't merge two objects of differing types");
}
if (t_B === "array") {
arrays(A, B, [], ops);
} else if (t_B === "object") {
objects(A, B, [], ops);
} else {
throw new Error("unsupported datatype" + t_B);
}
return ops;
};
var applyOp = function(O, op) {
var path;
var key;
var result;
switch (op.type) {
case "replace":
key = op.path[op.path.length - 1];
path = op.path.slice(0, op.path.length - 1);
var parent = find(O, path);
if (!parent) {
throw new Error("cannot apply change to non-existent element");
}
parent[key] = op.value;
break;
case "splice":
var found = find(O, op.path);
if (!found) {
console.error("[applyOp] expected path [%s] to exist in object", op.path.join(","));
throw new Error("Path did not exist");
}
if (type(found) !== "array") {
throw new Error("Can't splice non-array");
}
Array.prototype.splice.apply(found, [ op.offset, op.removals ].concat(op.value));
break;
case "remove":
key = op.path[op.path.length - 1];
path = op.path.slice(0, op.path.length - 1);
result = find(O, path);
if (typeof result !== "undefined") {
delete result[key];
}
break;
default:
throw new Error("unsupported operation type");
}
};
var patch = function(O, ops) {
ops.forEach((function(op) {
applyOp(O, op);
}));
return O;
};
var arbiter = function(p_a, p_b, c) {
if (p_a.prev !== p_b.prev) {
throw new Error("Parent values don't match!");
}
if (c === CASES.splice.splice) {
console.log(p_a);
console.log(p_b);
console.log("\n\n\n\n\n\n\n\n\n");
return true;
}
var o = p_a.prev;
var ops_a = Diff.diff(o, p_a.value);
var ops_b = Diff.diff(o, p_b.value);
var ops_x = TextTransformer(ops_b, ops_a, o);
var x2 = Operation.applyMulti(ops_a, o);
var x3 = Operation.applyMulti(ops_x, x2);
p_b.value = x3;
};
module.exports = function(opsToTransform, opsTransformBy, s_orig) {
var o_orig = JSON.parse(s_orig);
var s_transformBy = Operation.applyMulti(opsTransformBy, s_orig);
var o_transformBy = JSON.parse(s_transformBy);
var s_toTransform = Operation.applyMulti(opsToTransform, s_orig);
var o_toTransform = JSON.parse(s_toTransform);
try {
var diffTTF = diff(o_orig, o_toTransform);
var diffTFB = diff(o_orig, o_transformBy);
var newDiffTTF = resolve(diffTFB, diffTTF, arbiter);
patch(o_orig, diffTFB);
patch(o_orig, newDiffTTF);
var result = Sortify(o_orig);
var ret = Diff.diff(s_transformBy, result);
return ret;
} catch (err) {
console.error(err);
}
return [];
};
module.exports._ = {
clone,
pathOverlaps,
deepEqual,
diff,
resolve,
patch,
arbiter
};
}
};
r.m[1] = {
"dist/JSON.sortify.js": function(module, exports, require) {
(function(factory) {
if (typeof module !== "undefined" && module.exports) module.exports = factory(); else JSON.sortify = factory();
})((function() {
var sortKeys = function sortKeys(o) {
if (Array.isArray(o)) {
return o.map(sortKeys);
} else if (o instanceof Object) {
var _ret = function() {
var numeric = [];
var nonNumeric = [];
Object.keys(o).forEach((function(key) {
if (/^(0|[1-9][0-9]*)$/.test(key)) {
numeric.push(+key);
} else {
nonNumeric.push(key);
}
}));
return {
v: numeric.sort((function(a, b) {
return a - b;
})).concat(nonNumeric.sort()).reduce((function(result, key) {
result[key] = sortKeys(o[key]);
return result;
}), {})
};
}();
if (typeof _ret === "object") return _ret.v;
}
return o;
};
var jsonStringify = JSON.stringify.bind(JSON);
var sortify = function sortify(value, replacer, space) {
var nativeJson = jsonStringify(value, replacer, 0);
if (!nativeJson || nativeJson[0] !== "{" && nativeJson[0] !== "[") {
return nativeJson;
}
var cleanObj = JSON.parse(nativeJson);
return jsonStringify(sortKeys(cleanObj), null, space);
};
return sortify;
}));
}
};
r.m[2] = {
"diff.js": function(module, exports, require) {
var DIFF_DELETE = -1;
var DIFF_INSERT = 1;
var DIFF_EQUAL = 0;
function diff_main(text1, text2, cursor_pos, _fix_unicode) {
if (text1 === text2) {
if (text1) {
return [ [ DIFF_EQUAL, text1 ] ];
}
return [];
}
if (cursor_pos != null) {
var editdiff = find_cursor_edit_diff(text1, text2, cursor_pos);
if (editdiff) {
return editdiff;
}
}
var commonlength = diff_commonPrefix(text1, text2);
var commonprefix = text1.substring(0, commonlength);
text1 = text1.substring(commonlength);
text2 = text2.substring(commonlength);
commonlength = diff_commonSuffix(text1, text2);
var commonsuffix = text1.substring(text1.length - commonlength);
text1 = text1.substring(0, text1.length - commonlength);
text2 = text2.substring(0, text2.length - commonlength);
var diffs = diff_compute_(text1, text2);
if (commonprefix) {
diffs.unshift([ DIFF_EQUAL, commonprefix ]);
}
if (commonsuffix) {
diffs.push([ DIFF_EQUAL, commonsuffix ]);
}
diff_cleanupMerge(diffs, _fix_unicode);
return diffs;
}
function diff_compute_(text1, text2) {
var diffs;
if (!text1) {
return [ [ DIFF_INSERT, text2 ] ];
}
if (!text2) {
return [ [ DIFF_DELETE, text1 ] ];
}
var longtext = text1.length > text2.length ? text1 : text2;
var shorttext = text1.length > text2.length ? text2 : text1;
var i = longtext.indexOf(shorttext);
if (i !== -1) {
diffs = [ [ DIFF_INSERT, longtext.substring(0, i) ], [ DIFF_EQUAL, shorttext ], [ DIFF_INSERT, longtext.substring(i + shorttext.length) ] ];
if (text1.length > text2.length) {
diffs[0][0] = diffs[2][0] = DIFF_DELETE;
}
return diffs;
}
if (shorttext.length === 1) {
return [ [ DIFF_DELETE, text1 ], [ DIFF_INSERT, text2 ] ];
}
var hm = diff_halfMatch_(text1, text2);
if (hm) {
var text1_a = hm[0];
var text1_b = hm[1];
var text2_a = hm[2];
var text2_b = hm[3];
var mid_common = hm[4];
var diffs_a = diff_main(text1_a, text2_a);
var diffs_b = diff_main(text1_b, text2_b);
return diffs_a.concat([ [ DIFF_EQUAL, mid_common ] ], diffs_b);
}
return diff_bisect_(text1, text2);
}
function diff_bisect_(text1, text2) {
var text1_length = text1.length;
var text2_length = text2.length;
var max_d = Math.ceil((text1_length + text2_length) / 2);
var v_offset = max_d;
var v_length = 2 * max_d;
var v1 = new Array(v_length);
var v2 = new Array(v_length);
for (var x = 0; x < v_length; x++) {
v1[x] = -1;
v2[x] = -1;
}
v1[v_offset + 1] = 0;
v2[v_offset + 1] = 0;
var delta = text1_length - text2_length;
var front = delta % 2 !== 0;
var k1start = 0;
var k1end = 0;
var k2start = 0;
var k2end = 0;
for (var d = 0; d < max_d; d++) {
for (var k1 = -d + k1start; k1 <= d - k1end; k1 += 2) {
var k1_offset = v_offset + k1;
var x1;
if (k1 === -d || k1 !== d && v1[k1_offset - 1] < v1[k1_offset + 1]) {
x1 = v1[k1_offset + 1];
} else {
x1 = v1[k1_offset - 1] + 1;
}
var y1 = x1 - k1;
while (x1 < text1_length && y1 < text2_length && text1.charAt(x1) === text2.charAt(y1)) {
x1++;
y1++;
}
v1[k1_offset] = x1;
if (x1 > text1_length) {
k1end += 2;
} else if (y1 > text2_length) {
k1start += 2;
} else if (front) {
var k2_offset = v_offset + delta - k1;
if (k2_offset >= 0 && k2_offset < v_length && v2[k2_offset] !== -1) {
var x2 = text1_length - v2[k2_offset];
if (x1 >= x2) {
return diff_bisectSplit_(text1, text2, x1, y1);
}
}
}
}
for (var k2 = -d + k2start; k2 <= d - k2end; k2 += 2) {
var k2_offset = v_offset + k2;
var x2;
if (k2 === -d || k2 !== d && v2[k2_offset - 1] < v2[k2_offset + 1]) {
x2 = v2[k2_offset + 1];
} else {
x2 = v2[k2_offset - 1] + 1;
}
var y2 = x2 - k2;
while (x2 < text1_length && y2 < text2_length && text1.charAt(text1_length - x2 - 1) === text2.charAt(text2_length - y2 - 1)) {
x2++;
y2++;
}
v2[k2_offset] = x2;
if (x2 > text1_length) {
k2end += 2;
} else if (y2 > text2_length) {
k2start += 2;
} else if (!front) {
var k1_offset = v_offset + delta - k2;
if (k1_offset >= 0 && k1_offset < v_length && v1[k1_offset] !== -1) {
var x1 = v1[k1_offset];
var y1 = v_offset + x1 - k1_offset;
x2 = text1_length - x2;
if (x1 >= x2) {
return diff_bisectSplit_(text1, text2, x1, y1);
}
}
}
}
}
return [ [ DIFF_DELETE, text1 ], [ DIFF_INSERT, text2 ] ];
}
function diff_bisectSplit_(text1, text2, x, y) {
var text1a = text1.substring(0, x);
var text2a = text2.substring(0, y);
var text1b = text1.substring(x);
var text2b = text2.substring(y);
var diffs = diff_main(text1a, text2a);
var diffsb = diff_main(text1b, text2b);
return diffs.concat(diffsb);
}
function diff_commonPrefix(text1, text2) {
if (!text1 || !text2 || text1.charAt(0) !== text2.charAt(0)) {
return 0;
}
var pointermin = 0;
var pointermax = Math.min(text1.length, text2.length);
var pointermid = pointermax;
var pointerstart = 0;
while (pointermin < pointermid) {
if (text1.substring(pointerstart, pointermid) == text2.substring(pointerstart, pointermid)) {
pointermin = pointermid;
pointerstart = pointermin;
} else {
pointermax = pointermid;
}
pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
}
if (is_surrogate_pair_start(text1.charCodeAt(pointermid - 1))) {
pointermid--;
}
return pointermid;
}
function diff_commonSuffix(text1, text2) {
if (!text1 || !text2 || text1.slice(-1) !== text2.slice(-1)) {
return 0;
}
var pointermin = 0;
var pointermax = Math.min(text1.length, text2.length);
var pointermid = pointermax;
var pointerend = 0;
while (pointermin < pointermid) {
if (text1.substring(text1.length - pointermid, text1.length - pointerend) == text2.substring(text2.length - pointermid, text2.length - pointerend)) {
pointermin = pointermid;
pointerend = pointermin;
} else {
pointermax = pointermid;
}
pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
}
if (is_surrogate_pair_end(text1.charCodeAt(text1.length - pointermid))) {
pointermid--;
}
return pointermid;
}
function diff_halfMatch_(text1, text2) {
var longtext = text1.length > text2.length ? text1 : text2;
var shorttext = text1.length > text2.length ? text2 : text1;
if (longtext.length < 4 || shorttext.length * 2 < longtext.length) {
return null;
}
function diff_halfMatchI_(longtext, shorttext, i) {
var seed = longtext.substring(i, i + Math.floor(longtext.length / 4));
var j = -1;
var best_common = "";
var best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b;
while ((j = shorttext.indexOf(seed, j + 1)) !== -1) {
var prefixLength = diff_commonPrefix(longtext.substring(i), shorttext.substring(j));
var suffixLength = diff_commonSuffix(longtext.substring(0, i), shorttext.substring(0, j));
if (best_common.length < suffixLength + prefixLength) {
best_common = shorttext.substring(j - suffixLength, j) + shorttext.substring(j, j + prefixLength);
best_longtext_a = longtext.substring(0, i - suffixLength);
best_longtext_b = longtext.substring(i + prefixLength);
best_shorttext_a = shorttext.substring(0, j - suffixLength);
best_shorttext_b = shorttext.substring(j + prefixLength);
}
}
if (best_common.length * 2 >= longtext.length) {
return [ best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b, best_common ];
} else {
return null;
}
}
var hm1 = diff_halfMatchI_(longtext, shorttext, Math.ceil(longtext.length / 4));
var hm2 = diff_halfMatchI_(longtext, shorttext, Math.ceil(longtext.length / 2));
var hm;
if (!hm1 && !hm2) {
return null;
} else if (!hm2) {
hm = hm1;
} else if (!hm1) {
hm = hm2;
} else {
hm = hm1[4].length > hm2[4].length ? hm1 : hm2;
}
var text1_a, text1_b, text2_a, text2_b;
if (text1.length > text2.length) {
text1_a = hm[0];
text1_b = hm[1];
text2_a = hm[2];
text2_b = hm[3];
} else {
text2_a = hm[0];
text2_b = hm[1];
text1_a = hm[2];
text1_b = hm[3];
}
var mid_common = hm[4];
return [ text1_a, text1_b, text2_a, text2_b, mid_common ];
}
function diff_cleanupMerge(diffs, fix_unicode) {
diffs.push([ DIFF_EQUAL, "" ]);
var pointer = 0;
var count_delete = 0;
var count_insert = 0;
var text_delete = "";
var text_insert = "";
var commonlength;
while (pointer < diffs.length) {
if (pointer < diffs.length - 1 && !diffs[pointer][1]) {
diffs.splice(pointer, 1);
continue;
}
switch (diffs[pointer][0]) {
case DIFF_INSERT:
count_insert++;
text_insert += diffs[pointer][1];
pointer++;
break;
case DIFF_DELETE:
count_delete++;
text_delete += diffs[pointer][1];
pointer++;
break;
case DIFF_EQUAL:
var previous_equality = pointer - count_insert - count_delete - 1;
if (fix_unicode) {
if (previous_equality >= 0 && ends_with_pair_start(diffs[previous_equality][1])) {
var stray = diffs[previous_equality][1].slice(-1);
diffs[previous_equality][1] = diffs[previous_equality][1].slice(0, -1);
text_delete = stray + text_delete;
text_insert = stray + text_insert;
if (!diffs[previous_equality][1]) {
diffs.splice(previous_equality, 1);
pointer--;
var k = previous_equality - 1;
if (diffs[k] && diffs[k][0] === DIFF_INSERT) {
count_insert++;
text_insert = diffs[k][1] + text_insert;
k--;
}
if (diffs[k] && diffs[k][0] === DIFF_DELETE) {
count_delete++;
text_delete = diffs[k][1] + text_delete;
k--;
}
previous_equality = k;
}
}
if (starts_with_pair_end(diffs[pointer][1])) {
var stray = diffs[pointer][1].charAt(0);
diffs[pointer][1] = diffs[pointer][1].slice(1);
text_delete += stray;
text_insert += stray;
}
}
if (pointer < diffs.length - 1 && !diffs[pointer][1]) {
diffs.splice(pointer, 1);
break;
}
if (text_delete.length > 0 || text_insert.length > 0) {
if (text_delete.length > 0 && text_insert.length > 0) {
commonlength = diff_commonPrefix(text_insert, text_delete);
if (commonlength !== 0) {
if (previous_equality >= 0) {
diffs[previous_equality][1] += text_insert.substring(0, commonlength);
} else {
diffs.splice(0, 0, [ DIFF_EQUAL, text_insert.substring(0, commonlength) ]);
pointer++;
}
text_insert = text_insert.substring(commonlength);
text_delete = text_delete.substring(commonlength);
}
commonlength = diff_commonSuffix(text_insert, text_delete);
if (commonlength !== 0) {
diffs[pointer][1] = text_insert.substring(text_insert.length - commonlength) + diffs[pointer][1];
text_insert = text_insert.substring(0, text_insert.length - commonlength);
text_delete = text_delete.substring(0, text_delete.length - commonlength);
}
}
var n = count_insert + count_delete;
if (text_delete.length === 0 && text_insert.length === 0) {
diffs.splice(pointer - n, n);
pointer = pointer - n;
} else if (text_delete.length === 0) {
diffs.splice(pointer - n, n, [ DIFF_INSERT, text_insert ]);
pointer = pointer - n + 1;
} else if (text_insert.length === 0) {
diffs.splice(pointer - n, n, [ DIFF_DELETE, text_delete ]);
pointer = pointer - n + 1;
} else {
diffs.splice(pointer - n, n, [ DIFF_DELETE, text_delete ], [ DIFF_INSERT, text_insert ]);
pointer = pointer - n + 2;
}
}
if (pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL) {
diffs[pointer - 1][1] += diffs[pointer][1];
diffs.splice(pointer, 1);
} else {
pointer++;
}
count_insert = 0;
count_delete = 0;
text_delete = "";
text_insert = "";
break;
}
}
if (diffs[diffs.length - 1][1] === "") {
diffs.pop();
}
var changes = false;
pointer = 1;
while (pointer < diffs.length - 1) {
if (diffs[pointer - 1][0] === DIFF_EQUAL && diffs[pointer + 1][0] === DIFF_EQUAL) {
if (diffs[pointer][1].substring(diffs[pointer][1].length - diffs[pointer - 1][1].length) === diffs[pointer - 1][1]) {
diffs[pointer][1] = diffs[pointer - 1][1] + diffs[pointer][1].substring(0, diffs[pointer][1].length - diffs[pointer - 1][1].length);
diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1];
diffs.splice(pointer - 1, 1);
changes = true;
} else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) == diffs[pointer + 1][1]) {
diffs[pointer - 1][1] += diffs[pointer + 1][1];
diffs[pointer][1] = diffs[pointer][1].substring(diffs[pointer + 1][1].length) + diffs[pointer + 1][1];
diffs.splice(pointer + 1, 1);
changes = true;
}
}
pointer++;
}
if (changes) {
diff_cleanupMerge(diffs, fix_unicode);
}
}
function is_surrogate_pair_start(charCode) {
return charCode >= 55296 && charCode <= 56319;
}
function is_surrogate_pair_end(charCode) {
return charCode >= 56320 && charCode <= 57343;
}
function starts_with_pair_end(str) {
return is_surrogate_pair_end(str.charCodeAt(0));
}
function ends_with_pair_start(str) {
return is_surrogate_pair_start(str.charCodeAt(str.length - 1));
}
function remove_empty_tuples(tuples) {
var ret = [];
for (var i = 0; i < tuples.length; i++) {
if (tuples[i][1].length > 0) {
ret.push(tuples[i]);
}
}
return ret;
}
function make_edit_splice(before, oldMiddle, newMiddle, after) {
if (ends_with_pair_start(before) || starts_with_pair_end(after)) {
return null;
}
return remove_empty_tuples([ [ DIFF_EQUAL, before ], [ DIFF_DELETE, oldMiddle ], [ DIFF_INSERT, newMiddle ], [ DIFF_EQUAL, after ] ]);
}
function find_cursor_edit_diff(oldText, newText, cursor_pos) {
var oldRange = typeof cursor_pos === "number" ? {
index: cursor_pos,
length: 0
} : cursor_pos.oldRange;
var newRange = typeof cursor_pos === "number" ? null : cursor_pos.newRange;
var oldLength = oldText.length;
var newLength = newText.length;
if (oldRange.length === 0 && (newRange === null || newRange.length === 0)) {
var oldCursor = oldRange.index;
var oldBefore = oldText.slice(0, oldCursor);
var oldAfter = oldText.slice(oldCursor);
var maybeNewCursor = newRange ? newRange.index : null;
editBefore: {
var newCursor = oldCursor + newLength - oldLength;
if (maybeNewCursor !== null && maybeNewCursor !== newCursor) {
break editBefore;
}
if (newCursor < 0 || newCursor > newLength) {
break editBefore;
}
var newBefore = newText.slice(0, newCursor);
var newAfter = newText.slice(newCursor);
if (newAfter !== oldAfter) {
break editBefore;
}
var prefixLength = Math.min(oldCursor, newCursor);
var oldPrefix = oldBefore.slice(0, prefixLength);
var newPrefix = newBefore.slice(0, prefixLength);
if (oldPrefix !== newPrefix) {
break editBefore;
}
var oldMiddle = oldBefore.slice(prefixLength);
var newMiddle = newBefore.slice(prefixLength);
return make_edit_splice(oldPrefix, oldMiddle, newMiddle, oldAfter);
}
editAfter: {
if (maybeNewCursor !== null && maybeNewCursor !== oldCursor) {
break editAfter;
}
var cursor = oldCursor;
var newBefore = newText.slice(0, cursor);
var newAfter = newText.slice(cursor);
if (newBefore !== oldBefore) {
break editAfter;
}
var suffixLength = Math.min(oldLength - cursor, newLength - cursor);
var oldSuffix = oldAfter.slice(oldAfter.length - suffixLength);
var newSuffix = newAfter.slice(newAfter.length - suffixLength);
if (oldSuffix !== newSuffix) {
break editAfter;
}
var oldMiddle = oldAfter.slice(0, oldAfter.length - suffixLength);
var newMiddle = newAfter.slice(0, newAfter.length - suffixLength);
return make_edit_splice(oldBefore, oldMiddle, newMiddle, oldSuffix);
}
}
if (oldRange.length > 0 && newRange && newRange.length === 0) {
replaceRange: {
var oldPrefix = oldText.slice(0, oldRange.index);
var oldSuffix = oldText.slice(oldRange.index + oldRange.length);
var prefixLength = oldPrefix.length;
var suffixLength = oldSuffix.length;
if (newLength < prefixLength + suffixLength) {
break replaceRange;
}
var newPrefix = newText.slice(0, prefixLength);
var newSuffix = newText.slice(newLength - suffixLength);
if (oldPrefix !== newPrefix || oldSuffix !== newSuffix) {
break replaceRange;
}
var oldMiddle = oldText.slice(prefixLength, oldLength - suffixLength);
var newMiddle = newText.slice(prefixLength, newLength - suffixLength);
return make_edit_splice(oldPrefix, oldMiddle, newMiddle, oldSuffix);
}
}
return null;
}
function diff(text1, text2, cursor_pos) {
return diff_main(text1, text2, cursor_pos, true);
}
diff.INSERT = DIFF_INSERT;
diff.DELETE = DIFF_DELETE;
diff.EQUAL = DIFF_EQUAL;
module.exports = diff;
}
};
function umd(n, f) {
module.exports = n;
var e;
"undefined" != typeof window ? e = window : "undefined" != typeof commonjsGlobal ? e = commonjsGlobal : "undefined" != typeof self && (e = self),
e[f] = n;
}
umd(r("ChainPad.js"), "ChainPad");
})();
})(chainpad_dist$1);
return chainpad_dist$1.exports;
}
var chainpad_distExports = requireChainpad_dist();
var chainpad_dist = getDefaultExportFromCjs(chainpad_distExports);
var ChainPad = _mergeNamespaces({
__proto__: null,
default: chainpad_dist
}, [ chainpad_distExports ]);
var crypto = {
exports: {}
};
var naclFast = {
exports: {}
};
var hasRequiredNaclFast;
function requireNaclFast() {
if (hasRequiredNaclFast) return naclFast.exports;
hasRequiredNaclFast = 1;
(function(module) {
(function(nacl) {
var gf = function(init) {
var i, r = new Float64Array(16);
if (init) for (i = 0; i < init.length; i++) r[i] = init[i];
return r;
};
var randombytes = function() {
throw new Error("no PRNG");
};
var _0 = new Uint8Array(16);
var _9 = new Uint8Array(32);
_9[0] = 9;
var gf0 = gf(), gf1 = gf([ 1 ]), _121665 = gf([ 56129, 1 ]), D = gf([ 30883, 4953, 19914, 30187, 55467, 16705, 2637, 112, 59544, 30585, 16505, 36039, 65139, 11119, 27886, 20995 ]), D2 = gf([ 61785, 9906, 39828, 60374, 45398, 33411, 5274, 224, 53552, 61171, 33010, 6542, 64743, 22239, 55772, 9222 ]), X = gf([ 54554, 36645, 11616, 51542, 42930, 38181, 51040, 26924, 56412, 64982, 57905, 49316, 21502, 52590, 14035, 8553 ]), Y = gf([ 26200, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214 ]), I = gf([ 41136, 18958, 6951, 50414, 58488, 44335, 6150, 12099, 55207, 15867, 153, 11085, 57099, 20417, 9344, 11139 ]);
function ts64(x, i, h, l) {
x[i] = h >> 24 & 255;
x[i + 1] = h >> 16 & 255;
x[i + 2] = h >> 8 & 255;
x[i + 3] = h & 255;
x[i + 4] = l >> 24 & 255;
x[i + 5] = l >> 16 & 255;
x[i + 6] = l >> 8 & 255;
x[i + 7] = l & 255;
}
function vn(x, xi, y, yi, n) {
var i, d = 0;
for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i];
return (1 & d - 1 >>> 8) - 1;
}
function crypto_verify_16(x, xi, y, yi) {
return vn(x, xi, y, yi, 16);
}
function crypto_verify_32(x, xi, y, yi) {
return vn(x, xi, y, yi, 32);
}
function core_salsa20(o, p, k, c) {
var j0 = c[0] & 255 | (c[1] & 255) << 8 | (c[2] & 255) << 16 | (c[3] & 255) << 24, j1 = k[0] & 255 | (k[1] & 255) << 8 | (k[2] & 255) << 16 | (k[3] & 255) << 24, j2 = k[4] & 255 | (k[5] & 255) << 8 | (k[6] & 255) << 16 | (k[7] & 255) << 24, j3 = k[8] & 255 | (k[9] & 255) << 8 | (k[10] & 255) << 16 | (k[11] & 255) << 24, j4 = k[12] & 255 | (k[13] & 255) << 8 | (k[14] & 255) << 16 | (k[15] & 255) << 24, j5 = c[4] & 255 | (c[5] & 255) << 8 | (c[6] & 255) << 16 | (c[7] & 255) << 24, j6 = p[0] & 255 | (p[1] & 255) << 8 | (p[2] & 255) << 16 | (p[3] & 255) << 24, j7 = p[4] & 255 | (p[5] & 255) << 8 | (p[6] & 255) << 16 | (p[7] & 255) << 24, j8 = p[8] & 255 | (p[9] & 255) << 8 | (p[10] & 255) << 16 | (p[11] & 255) << 24, j9 = p[12] & 255 | (p[13] & 255) << 8 | (p[14] & 255) << 16 | (p[15] & 255) << 24, j10 = c[8] & 255 | (c[9] & 255) << 8 | (c[10] & 255) << 16 | (c[11] & 255) << 24, j11 = k[16] & 255 | (k[17] & 255) << 8 | (k[18] & 255) << 16 | (k[19] & 255) << 24, j12 = k[20] & 255 | (k[21] & 255) << 8 | (k[22] & 255) << 16 | (k[23] & 255) << 24, j13 = k[24] & 255 | (k[25] & 255) << 8 | (k[26] & 255) << 16 | (k[27] & 255) << 24, j14 = k[28] & 255 | (k[29] & 255) << 8 | (k[30] & 255) << 16 | (k[31] & 255) << 24, j15 = c[12] & 255 | (c[13] & 255) << 8 | (c[14] & 255) << 16 | (c[15] & 255) << 24;
var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, x15 = j15, u;
for (var i = 0; i < 20; i += 2) {
u = x0 + x12 | 0;
x4 ^= u << 7 | u >>> 32 - 7;
u = x4 + x0 | 0;
x8 ^= u << 9 | u >>> 32 - 9;
u = x8 + x4 | 0;
x12 ^= u << 13 | u >>> 32 - 13;
u = x12 + x8 | 0;
x0 ^= u << 18 | u >>> 32 - 18;
u = x5 + x1 | 0;
x9 ^= u << 7 | u >>> 32 - 7;
u = x9 + x5 | 0;
x13 ^= u << 9 | u >>> 32 - 9;
u = x13 + x9 | 0;
x1 ^= u << 13 | u >>> 32 - 13;
u = x1 + x13 | 0;
x5 ^= u << 18 | u >>> 32 - 18;
u = x10 + x6 | 0;
x14 ^= u << 7 | u >>> 32 - 7;
u = x14 + x10 | 0;
x2 ^= u << 9 | u >>> 32 - 9;
u = x2 + x14 | 0;
x6 ^= u << 13 | u >>> 32 - 13;
u = x6 + x2 | 0;
x10 ^= u << 18 | u >>> 32 - 18;
u = x15 + x11 | 0;
x3 ^= u << 7 | u >>> 32 - 7;
u = x3 + x15 | 0;
x7 ^= u << 9 | u >>> 32 - 9;
u = x7 + x3 | 0;
x11 ^= u << 13 | u >>> 32 - 13;
u = x11 + x7 | 0;
x15 ^= u << 18 | u >>> 32 - 18;
u = x0 + x3 | 0;
x1 ^= u << 7 | u >>> 32 - 7;
u = x1 + x0 | 0;
x2 ^= u << 9 | u >>> 32 - 9;
u = x2 + x1 | 0;
x3 ^= u << 13 | u >>> 32 - 13;
u = x3 + x2 | 0;
x0 ^= u << 18 | u >>> 32 - 18;
u = x5 + x4 | 0;
x6 ^= u << 7 | u >>> 32 - 7;
u = x6 + x5 | 0;
x7 ^= u << 9 | u >>> 32 - 9;
u = x7 + x6 | 0;
x4 ^= u << 13 | u >>> 32 - 13;
u = x4 + x7 | 0;
x5 ^= u << 18 | u >>> 32 - 18;
u = x10 + x9 | 0;
x11 ^= u << 7 | u >>> 32 - 7;
u = x11 + x10 | 0;
x8 ^= u << 9 | u >>> 32 - 9;
u = x8 + x11 | 0;
x9 ^= u << 13 | u >>> 32 - 13;
u = x9 + x8 | 0;
x10 ^= u << 18 | u >>> 32 - 18;
u = x15 + x14 | 0;
x12 ^= u << 7 | u >>> 32 - 7;
u = x12 + x15 | 0;
x13 ^= u << 9 | u >>> 32 - 9;
u = x13 + x12 | 0;
x14 ^= u << 13 | u >>> 32 - 13;
u = x14 + x13 | 0;
x15 ^= u << 18 | u >>> 32 - 18;
}
x0 = x0 + j0 | 0;
x1 = x1 + j1 | 0;
x2 = x2 + j2 | 0;
x3 = x3 + j3 | 0;
x4 = x4 + j4 | 0;
x5 = x5 + j5 | 0;
x6 = x6 + j6 | 0;
x7 = x7 + j7 | 0;
x8 = x8 + j8 | 0;
x9 = x9 + j9 | 0;
x10 = x10 + j10 | 0;
x11 = x11 + j11 | 0;
x12 = x12 + j12 | 0;
x13 = x13 + j13 | 0;
x14 = x14 + j14 | 0;
x15 = x15 + j15 | 0;
o[0] = x0 >>> 0 & 255;
o[1] = x0 >>> 8 & 255;
o[2] = x0 >>> 16 & 255;
o[3] = x0 >>> 24 & 255;
o[4] = x1 >>> 0 & 255;
o[5] = x1 >>> 8 & 255;
o[6] = x1 >>> 16 & 255;
o[7] = x1 >>> 24 & 255;
o[8] = x2 >>> 0 & 255;
o[9] = x2 >>> 8 & 255;
o[10] = x2 >>> 16 & 255;
o[11] = x2 >>> 24 & 255;
o[12] = x3 >>> 0 & 255;
o[13] = x3 >>> 8 & 255;
o[14] = x3 >>> 16 & 255;
o[15] = x3 >>> 24 & 255;
o[16] = x4 >>> 0 & 255;
o[17] = x4 >>> 8 & 255;
o[18] = x4 >>> 16 & 255;
o[19] = x4 >>> 24 & 255;
o[20] = x5 >>> 0 & 255;
o[21] = x5 >>> 8 & 255;
o[22] = x5 >>> 16 & 255;
o[23] = x5 >>> 24 & 255;
o[24] = x6 >>> 0 & 255;
o[25] = x6 >>> 8 & 255;
o[26] = x6 >>> 16 & 255;
o[27] = x6 >>> 24 & 255;
o[28] = x7 >>> 0 & 255;
o[29] = x7 >>> 8 & 255;
o[30] = x7 >>> 16 & 255;
o[31] = x7 >>> 24 & 255;
o[32] = x8 >>> 0 & 255;
o[33] = x8 >>> 8 & 255;
o[34] = x8 >>> 16 & 255;
o[35] = x8 >>> 24 & 255;
o[36] = x9 >>> 0 & 255;
o[37] = x9 >>> 8 & 255;
o[38] = x9 >>> 16 & 255;
o[39] = x9 >>> 24 & 255;
o[40] = x10 >>> 0 & 255;
o[41] = x10 >>> 8 & 255;
o[42] = x10 >>> 16 & 255;
o[43] = x10 >>> 24 & 255;
o[44] = x11 >>> 0 & 255;
o[45] = x11 >>> 8 & 255;
o[46] = x11 >>> 16 & 255;
o[47] = x11 >>> 24 & 255;
o[48] = x12 >>> 0 & 255;
o[49] = x12 >>> 8 & 255;
o[50] = x12 >>> 16 & 255;
o[51] = x12 >>> 24 & 255;
o[52] = x13 >>> 0 & 255;
o[53] = x13 >>> 8 & 255;
o[54] = x13 >>> 16 & 255;
o[55] = x13 >>> 24 & 255;
o[56] = x14 >>> 0 & 255;
o[57] = x14 >>> 8 & 255;
o[58] = x14 >>> 16 & 255;
o[59] = x14 >>> 24 & 255;
o[60] = x15 >>> 0 & 255;
o[61] = x15 >>> 8 & 255;
o[62] = x15 >>> 16 & 255;
o[63] = x15 >>> 24 & 255;
}
function core_hsalsa20(o, p, k, c) {
var j0 = c[0] & 255 | (c[1] & 255) << 8 | (c[2] & 255) << 16 | (c[3] & 255) << 24, j1 = k[0] & 255 | (k[1] & 255) << 8 | (k[2] & 255) << 16 | (k[3] & 255) << 24, j2 = k[4] & 255 | (k[5] & 255) << 8 | (k[6] & 255) << 16 | (k[7] & 255) << 24, j3 = k[8] & 255 | (k[9] & 255) << 8 | (k[10] & 255) << 16 | (k[11] & 255) << 24, j4 = k[12] & 255 | (k[13] & 255) << 8 | (k[14] & 255) << 16 | (k[15] & 255) << 24, j5 = c[4] & 255 | (c[5] & 255) << 8 | (c[6] & 255) << 16 | (c[7] & 255) << 24, j6 = p[0] & 255 | (p[1] & 255) << 8 | (p[2] & 255) << 16 | (p[3] & 255) << 24, j7 = p[4] & 255 | (p[5] & 255) << 8 | (p[6] & 255) << 16 | (p[7] & 255) << 24, j8 = p[8] & 255 | (p[9] & 255) << 8 | (p[10] & 255) << 16 | (p[11] & 255) << 24, j9 = p[12] & 255 | (p[13] & 255) << 8 | (p[14] & 255) << 16 | (p[15] & 255) << 24, j10 = c[8] & 255 | (c[9] & 255) << 8 | (c[10] & 255) << 16 | (c[11] & 255) << 24, j11 = k[16] & 255 | (k[17] & 255) << 8 | (k[18] & 255) << 16 | (k[19] & 255) << 24, j12 = k[20] & 255 | (k[21] & 255) << 8 | (k[22] & 255) << 16 | (k[23] & 255) << 24, j13 = k[24] & 255 | (k[25] & 255) << 8 | (k[26] & 255) << 16 | (k[27] & 255) << 24, j14 = k[28] & 255 | (k[29] & 255) << 8 | (k[30] & 255) << 16 | (k[31] & 255) << 24, j15 = c[12] & 255 | (c[13] & 255) << 8 | (c[14] & 255) << 16 | (c[15] & 255) << 24;
var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, x15 = j15, u;
for (var i = 0; i < 20; i += 2) {
u = x0 + x12 | 0;
x4 ^= u << 7 | u >>> 32 - 7;
u = x4 + x0 | 0;
x8 ^= u << 9 | u >>> 32 - 9;
u = x8 + x4 | 0;
x12 ^= u << 13 | u >>> 32 - 13;
u = x12 + x8 | 0;
x0 ^= u << 18 | u >>> 32 - 18;
u = x5 + x1 | 0;
x9 ^= u << 7 | u >>> 32 - 7;
u = x9 + x5 | 0;
x13 ^= u << 9 | u >>> 32 - 9;
u = x13 + x9 | 0;
x1 ^= u << 13 | u >>> 32 - 13;
u = x1 + x13 | 0;
x5 ^= u << 18 | u >>> 32 - 18;
u = x10 + x6 | 0;
x14 ^= u << 7 | u >>> 32 - 7;
u = x14 + x10 | 0;
x2 ^= u << 9 | u >>> 32 - 9;
u = x2 + x14 | 0;
x6 ^= u << 13 | u >>> 32 - 13;
u = x6 + x2 | 0;
x10 ^= u << 18 | u >>> 32 - 18;
u = x15 + x11 | 0;
x3 ^= u << 7 | u >>> 32 - 7;
u = x3 + x15 | 0;
x7 ^= u << 9 | u >>> 32 - 9;
u = x7 + x3 | 0;
x11 ^= u << 13 | u >>> 32 - 13;
u = x11 + x7 | 0;
x15 ^= u << 18 | u >>> 32 - 18;
u = x0 + x3 | 0;
x1 ^= u << 7 | u >>> 32 - 7;
u = x1 + x0 | 0;
x2 ^= u << 9 | u >>> 32 - 9;
u = x2 + x1 | 0;
x3 ^= u << 13 | u >>> 32 - 13;
u = x3 + x2 | 0;
x0 ^= u << 18 | u >>> 32 - 18;
u = x5 + x4 | 0;
x6 ^= u << 7 | u >>> 32 - 7;
u = x6 + x5 | 0;
x7 ^= u << 9 | u >>> 32 - 9;
u = x7 + x6 | 0;
x4 ^= u << 13 | u >>> 32 - 13;
u = x4 + x7 | 0;
x5 ^= u << 18 | u >>> 32 - 18;
u = x10 + x9 | 0;
x11 ^= u << 7 | u >>> 32 - 7;
u = x11 + x10 | 0;
x8 ^= u << 9 | u >>> 32 - 9;
u = x8 + x11 | 0;
x9 ^= u << 13 | u >>> 32 - 13;
u = x9 + x8 | 0;
x10 ^= u << 18 | u >>> 32 - 18;
u = x15 + x14 | 0;
x12 ^= u << 7 | u >>> 32 - 7;
u = x12 + x15 | 0;
x13 ^= u << 9 | u >>> 32 - 9;
u = x13 + x12 | 0;
x14 ^= u << 13 | u >>> 32 - 13;
u = x14 + x13 | 0;
x15 ^= u << 18 | u >>> 32 - 18;
}
o[0] = x0 >>> 0 & 255;
o[1] = x0 >>> 8 & 255;
o[2] = x0 >>> 16 & 255;
o[3] = x0 >>> 24 & 255;
o[4] = x5 >>> 0 & 255;
o[5] = x5 >>> 8 & 255;
o[6] = x5 >>> 16 & 255;
o[7] = x5 >>> 24 & 255;
o[8] = x10 >>> 0 & 255;
o[9] = x10 >>> 8 & 255;
o[10] = x10 >>> 16 & 255;
o[11] = x10 >>> 24 & 255;
o[12] = x15 >>> 0 & 255;
o[13] = x15 >>> 8 & 255;
o[14] = x15 >>> 16 & 255;
o[15] = x15 >>> 24 & 255;
o[16] = x6 >>> 0 & 255;
o[17] = x6 >>> 8 & 255;
o[18] = x6 >>> 16 & 255;
o[19] = x6 >>> 24 & 255;
o[20] = x7 >>> 0 & 255;
o[21] = x7 >>> 8 & 255;
o[22] = x7 >>> 16 & 255;
o[23] = x7 >>> 24 & 255;
o[24] = x8 >>> 0 & 255;
o[25] = x8 >>> 8 & 255;
o[26] = x8 >>> 16 & 255;
o[27] = x8 >>> 24 & 255;
o[28] = x9 >>> 0 & 255;
o[29] = x9 >>> 8 & 255;
o[30] = x9 >>> 16 & 255;
o[31] = x9 >>> 24 & 255;
}
function crypto_core_salsa20(out, inp, k, c) {
core_salsa20(out, inp, k, c);
}
function crypto_core_hsalsa20(out, inp, k, c) {
core_hsalsa20(out, inp, k, c);
}
var sigma = new Uint8Array([ 101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107 ]);
function crypto_stream_salsa20_xor(c, cpos, m, mpos, b, n, k) {
var z = new Uint8Array(16), x = new Uint8Array(64);
var u, i;
for (i = 0; i < 16; i++) z[i] = 0;
for (i = 0; i < 8; i++) z[i] = n[i];
while (b >= 64) {
crypto_core_salsa20(x, z, k, sigma);
for (i = 0; i < 64; i++) c[cpos + i] = m[mpos + i] ^ x[i];
u = 1;
for (i = 8; i < 16; i++) {
u = u + (z[i] & 255) | 0;
z[i] = u & 255;
u >>>= 8;
}
b -= 64;
cpos += 64;
mpos += 64;
}
if (b > 0) {
crypto_core_salsa20(x, z, k, sigma);
for (i = 0; i < b; i++) c[cpos + i] = m[mpos + i] ^ x[i];
}
return 0;
}
function crypto_stream_salsa20(c, cpos, b, n, k) {
var z = new Uint8Array(16), x = new Uint8Array(64);
var u, i;
for (i = 0; i < 16; i++) z[i] = 0;
for (i = 0; i < 8; i++) z[i] = n[i];
while (b >= 64) {
crypto_core_salsa20(x, z, k, sigma);
for (i = 0; i < 64; i++) c[cpos + i] = x[i];
u = 1;
for (i = 8; i < 16; i++) {
u = u + (z[i] & 255) | 0;
z[i] = u & 255;
u >>>= 8;
}
b -= 64;
cpos += 64;
}
if (b > 0) {
crypto_core_salsa20(x, z, k, sigma);
for (i = 0; i < b; i++) c[cpos + i] = x[i];
}
return 0;
}
function crypto_stream(c, cpos, d, n, k) {
var s = new Uint8Array(32);
crypto_core_hsalsa20(s, n, k, sigma);
var sn = new Uint8Array(8);
for (var i = 0; i < 8; i++) sn[i] = n[i + 16];
return crypto_stream_salsa20(c, cpos, d, sn, s);
}
function crypto_stream_xor(c, cpos, m, mpos, d, n, k) {
var s = new Uint8Array(32);
crypto_core_hsalsa20(s, n, k, sigma);
var sn = new Uint8Array(8);
for (var i = 0; i < 8; i++) sn[i] = n[i + 16];
return crypto_stream_salsa20_xor(c, cpos, m, mpos, d, sn, s);
}
var poly1305 = function(key) {
this.buffer = new Uint8Array(16);
this.r = new Uint16Array(10);
this.h = new Uint16Array(10);
this.pad = new Uint16Array(8);
this.leftover = 0;
this.fin = 0;
var t0, t1, t2, t3, t4, t5, t6, t7;
t0 = key[0] & 255 | (key[1] & 255) << 8;
this.r[0] = t0 & 8191;
t1 = key[2] & 255 | (key[3] & 255) << 8;
this.r[1] = (t0 >>> 13 | t1 << 3) & 8191;
t2 = key[4] & 255 | (key[5] & 255) << 8;
this.r[2] = (t1 >>> 10 | t2 << 6) & 7939;
t3 = key[6] & 255 | (key[7] & 255) << 8;
this.r[3] = (t2 >>> 7 | t3 << 9) & 8191;
t4 = key[8] & 255 | (key[9] & 255) << 8;
this.r[4] = (t3 >>> 4 | t4 << 12) & 255;
this.r[5] = t4 >>> 1 & 8190;
t5 = key[10] & 255 | (key[11] & 255) << 8;
this.r[6] = (t4 >>> 14 | t5 << 2) & 8191;
t6 = key[12] & 255 | (key[13] & 255) << 8;
this.r[7] = (t5 >>> 11 | t6 << 5) & 8065;
t7 = key[14] & 255 | (key[15] & 255) << 8;
this.r[8] = (t6 >>> 8 | t7 << 8) & 8191;
this.r[9] = t7 >>> 5 & 127;
this.pad[0] = key[16] & 255 | (key[17] & 255) << 8;
this.pad[1] = key[18] & 255 | (key[19] & 255) << 8;
this.pad[2] = key[20] & 255 | (key[21] & 255) << 8;
this.pad[3] = key[22] & 255 | (key[23] & 255) << 8;
this.pad[4] = key[24] & 255 | (key[25] & 255) << 8;
this.pad[5] = key[26] & 255 | (key[27] & 255) << 8;
this.pad[6] = key[28] & 255 | (key[29] & 255) << 8;
this.pad[7] = key[30] & 255 | (key[31] & 255) << 8;
};
poly1305.prototype.blocks = function(m, mpos, bytes) {
var hibit = this.fin ? 0 : 1 << 11;
var t0, t1, t2, t3, t4, t5, t6, t7, c;
var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9;
var h0 = this.h[0], h1 = this.h[1], h2 = this.h[2], h3 = this.h[3], h4 = this.h[4], h5 = this.h[5], h6 = this.h[6], h7 = this.h[7], h8 = this.h[8], h9 = this.h[9];
var r0 = this.r[0], r1 = this.r[1], r2 = this.r[2], r3 = this.r[3], r4 = this.r[4], r5 = this.r[5], r6 = this.r[6], r7 = this.r[7], r8 = this.r[8], r9 = this.r[9];
while (bytes >= 16) {
t0 = m[mpos + 0] & 255 | (m[mpos + 1] & 255) << 8;
h0 += t0 & 8191;
t1 = m[mpos + 2] & 255 | (m[mpos + 3] & 255) << 8;
h1 += (t0 >>> 13 | t1 << 3) & 8191;
t2 = m[mpos + 4] & 255 | (m[mpos + 5] & 255) << 8;
h2 += (t1 >>> 10 | t2 << 6) & 8191;
t3 = m[mpos + 6] & 255 | (m[mpos + 7] & 255) << 8;
h3 += (t2 >>> 7 | t3 << 9) & 8191;
t4 = m[mpos + 8] & 255 | (m[mpos + 9] & 255) << 8;
h4 += (t3 >>> 4 | t4 << 12) & 8191;
h5 += t4 >>> 1 & 8191;
t5 = m[mpos + 10] & 255 | (m[mpos + 11] & 255) << 8;
h6 += (t4 >>> 14 | t5 << 2) & 8191;
t6 = m[mpos + 12] & 255 | (m[mpos + 13] & 255) << 8;
h7 += (t5 >>> 11 | t6 << 5) & 8191;
t7 = m[mpos + 14] & 255 | (m[mpos + 15] & 255) << 8;
h8 += (t6 >>> 8 | t7 << 8) & 8191;
h9 += t7 >>> 5 | hibit;
c = 0;
d0 = c;
d0 += h0 * r0;
d0 += h1 * (5 * r9);
d0 += h2 * (5 * r8);
d0 += h3 * (5 * r7);
d0 += h4 * (5 * r6);
c = d0 >>> 13;
d0 &= 8191;
d0 += h5 * (5 * r5);
d0 += h6 * (5 * r4);
d0 += h7 * (5 * r3);
d0 += h8 * (5 * r2);
d0 += h9 * (5 * r1);
c += d0 >>> 13;
d0 &= 8191;
d1 = c;
d1 += h0 * r1;
d1 += h1 * r0;
d1 += h2 * (5 * r9);
d1 += h3 * (5 * r8);
d1 += h4 * (5 * r7);
c = d1 >>> 13;
d1 &= 8191;
d1 += h5 * (5 * r6);
d1 += h6 * (5 * r5);
d1 += h7 * (5 * r4);
d1 += h8 * (5 * r3);
d1 += h9 * (5 * r2);
c += d1 >>> 13;
d1 &= 8191;
d2 = c;
d2 += h0 * r2;
d2 += h1 * r1;
d2 += h2 * r0;
d2 += h3 * (5 * r9);
d2 += h4 * (5 * r8);
c = d2 >>> 13;
d2 &= 8191;
d2 += h5 * (5 * r7);
d2 += h6 * (5 * r6);
d2 += h7 * (5 * r5);
d2 += h8 * (5 * r4);
d2 += h9 * (5 * r3);
c += d2 >>> 13;
d2 &= 8191;
d3 = c;
d3 += h0 * r3;
d3 += h1 * r2;
d3 += h2 * r1;
d3 += h3 * r0;
d3 += h4 * (5 * r9);
c = d3 >>> 13;
d3 &= 8191;
d3 += h5 * (5 * r8);
d3 += h6 * (5 * r7);
d3 += h7 * (5 * r6);
d3 += h8 * (5 * r5);
d3 += h9 * (5 * r4);
c += d3 >>> 13;
d3 &= 8191;
d4 = c;
d4 += h0 * r4;
d4 += h1 * r3;
d4 += h2 * r2;
d4 += h3 * r1;
d4 += h4 * r0;
c = d4 >>> 13;
d4 &= 8191;
d4 += h5 * (5 * r9);
d4 += h6 * (5 * r8);
d4 += h7 * (5 * r7);
d4 += h8 * (5 * r6);
d4 += h9 * (5 * r5);
c += d4 >>> 13;
d4 &= 8191;
d5 = c;
d5 += h0 * r5;
d5 += h1 * r4;
d5 += h2 * r3;
d5 += h3 * r2;
d5 += h4 * r1;
c = d5 >>> 13;
d5 &= 8191;
d5 += h5 * r0;
d5 += h6 * (5 * r9);
d5 += h7 * (5 * r8);
d5 += h8 * (5 * r7);
d5 += h9 * (5 * r6);
c += d5 >>> 13;
d5 &= 8191;
d6 = c;
d6 += h0 * r6;
d6 += h1 * r5;
d6 += h2 * r4;
d6 += h3 * r3;
d6 += h4 * r2;
c = d6 >>> 13;
d6 &= 8191;
d6 += h5 * r1;
d6 += h6 * r0;
d6 += h7 * (5 * r9);
d6 += h8 * (5 * r8);
d6 += h9 * (5 * r7);
c += d6 >>> 13;
d6 &= 8191;
d7 = c;
d7 += h0 * r7;
d7 += h1 * r6;
d7 += h2 * r5;
d7 += h3 * r4;
d7 += h4 * r3;
c = d7 >>> 13;
d7 &= 8191;
d7 += h5 * r2;
d7 += h6 * r1;
d7 += h7 * r0;
d7 += h8 * (5 * r9);
d7 += h9 * (5 * r8);
c += d7 >>> 13;
d7 &= 8191;
d8 = c;
d8 += h0 * r8;
d8 += h1 * r7;
d8 += h2 * r6;
d8 += h3 * r5;
d8 += h4 * r4;
c = d8 >>> 13;
d8 &= 8191;
d8 += h5 * r3;
d8 += h6 * r2;
d8 += h7 * r1;
d8 += h8 * r0;
d8 += h9 * (5 * r9);
c += d8 >>> 13;
d8 &= 8191;
d9 = c;
d9 += h0 * r9;
d9 += h1 * r8;
d9 += h2 * r7;
d9 += h3 * r6;
d9 += h4 * r5;
c = d9 >>> 13;
d9 &= 8191;
d9 += h5 * r4;
d9 += h6 * r3;
d9 += h7 * r2;
d9 += h8 * r1;
d9 += h9 * r0;
c += d9 >>> 13;
d9 &= 8191;
c = (c << 2) + c | 0;
c = c + d0 | 0;
d0 = c & 8191;
c = c >>> 13;
d1 += c;
h0 = d0;
h1 = d1;
h2 = d2;
h3 = d3;
h4 = d4;
h5 = d5;
h6 = d6;
h7 = d7;
h8 = d8;
h9 = d9;
mpos += 16;
bytes -= 16;
}
this.h[0] = h0;
this.h[1] = h1;
this.h[2] = h2;
this.h[3] = h3;
this.h[4] = h4;
this.h[5] = h5;
this.h[6] = h6;
this.h[7] = h7;
this.h[8] = h8;
this.h[9] = h9;
};
poly1305.prototype.finish = function(mac, macpos) {
var g = new Uint16Array(10);
var c, mask, f, i;
if (this.leftover) {
i = this.leftover;
this.buffer[i++] = 1;
for (;i < 16; i++) this.buffer[i] = 0;
this.fin = 1;
this.blocks(this.buffer, 0, 16);
}
c = this.h[1] >>> 13;
this.h[1] &= 8191;
for (i = 2; i < 10; i++) {
this.h[i] += c;
c = this.h[i] >>> 13;
this.h[i] &= 8191;
}
this.h[0] += c * 5;
c = this.h[0] >>> 13;
this.h[0] &= 8191;
this.h[1] += c;
c = this.h[1] >>> 13;
this.h[1] &= 8191;
this.h[2] += c;
g[0] = this.h[0] + 5;
c = g[0] >>> 13;
g[0] &= 8191;
for (i = 1; i < 10; i++) {
g[i] = this.h[i] + c;
c = g[i] >>> 13;
g[i] &= 8191;
}
g[9] -= 1 << 13;
mask = (g[9] >>> 2 * 8 - 1) - 1;
for (i = 0; i < 10; i++) g[i] &= mask;
mask = ~mask;
for (i = 0; i < 10; i++) this.h[i] = this.h[i] & mask | g[i];
this.h[0] = (this.h[0] | this.h[1] << 13) & 65535;
this.h[1] = (this.h[1] >>> 3 | this.h[2] << 10) & 65535;
this.h[2] = (this.h[2] >>> 6 | this.h[3] << 7) & 65535;
this.h[3] = (this.h[3] >>> 9 | this.h[4] << 4) & 65535;
this.h[4] = (this.h[4] >>> 12 | this.h[5] << 1 | this.h[6] << 14) & 65535;
this.h[5] = (this.h[6] >>> 2 | this.h[7] << 11) & 65535;
this.h[6] = (this.h[7] >>> 5 | this.h[8] << 8) & 65535;
this.h[7] = (this.h[8] >>> 8 | this.h[9] << 5) & 65535;
f = this.h[0] + this.pad[0];
this.h[0] = f & 65535;
for (i = 1; i < 8; i++) {
f = (this.h[i] + this.pad[i] | 0) + (f >>> 16) | 0;
this.h[i] = f & 65535;
}
mac[macpos + 0] = this.h[0] >>> 0 & 255;
mac[macpos + 1] = this.h[0] >>> 8 & 255;
mac[macpos + 2] = this.h[1] >>> 0 & 255;
mac[macpos + 3] = this.h[1] >>> 8 & 255;
mac[macpos + 4] = this.h[2] >>> 0 & 255;
mac[macpos + 5] = this.h[2] >>> 8 & 255;
mac[macpos + 6] = this.h[3] >>> 0 & 255;
mac[macpos + 7] = this.h[3] >>> 8 & 255;
mac[macpos + 8] = this.h[4] >>> 0 & 255;
mac[macpos + 9] = this.h[4] >>> 8 & 255;
mac[macpos + 10] = this.h[5] >>> 0 & 255;
mac[macpos + 11] = this.h[5] >>> 8 & 255;
mac[macpos + 12] = this.h[6] >>> 0 & 255;
mac[macpos + 13] = this.h[6] >>> 8 & 255;
mac[macpos + 14] = this.h[7] >>> 0 & 255;
mac[macpos + 15] = this.h[7] >>> 8 & 255;
};
poly1305.prototype.update = function(m, mpos, bytes) {
var i, want;
if (this.leftover) {
want = 16 - this.leftover;
if (want > bytes) want = bytes;
for (i = 0; i < want; i++) this.buffer[this.leftover + i] = m[mpos + i];
bytes -= want;
mpos += want;
this.leftover += want;
if (this.leftover < 16) return;
this.blocks(buffer, 0, 16);
this.leftover = 0;
}
if (bytes >= 16) {
want = bytes - bytes % 16;
this.blocks(m, mpos, want);
mpos += want;
bytes -= want;
}
if (bytes) {
for (i = 0; i < bytes; i++) this.buffer[this.leftover + i] = m[mpos + i];
this.leftover += bytes;
}
};
function crypto_onetimeauth(out, outpos, m, mpos, n, k) {
var s = new poly1305(k);
s.update(m, mpos, n);
s.finish(out, outpos);
return 0;
}
function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) {
var x = new Uint8Array(16);
crypto_onetimeauth(x, 0, m, mpos, n, k);
return crypto_verify_16(h, hpos, x, 0);
}
function crypto_secretbox(c, m, d, n, k) {
var i;
if (d < 32) return -1;
crypto_stream_xor(c, 0, m, 0, d, n, k);
crypto_onetimeauth(c, 16, c, 32, d - 32, c);
for (i = 0; i < 16; i++) c[i] = 0;
return 0;
}
function crypto_secretbox_open(m, c, d, n, k) {
var i;
var x = new Uint8Array(32);
if (d < 32) return -1;
crypto_stream(x, 0, 32, n, k);
if (crypto_onetimeauth_verify(c, 16, c, 32, d - 32, x) !== 0) return -1;
crypto_stream_xor(m, 0, c, 0, d, n, k);
for (i = 0; i < 32; i++) m[i] = 0;
return 0;
}
function set25519(r, a) {
var i;
for (i = 0; i < 16; i++) r[i] = a[i] | 0;
}
function car25519(o) {
var i, v, c = 1;
for (i = 0; i < 16; i++) {
v = o[i] + c + 65535;
c = Math.floor(v / 65536);
o[i] = v - c * 65536;
}
o[0] += c - 1 + 37 * (c - 1);
}
function sel25519(p, q, b) {
var t, c = ~(b - 1);
for (var i = 0; i < 16; i++) {
t = c & (p[i] ^ q[i]);
p[i] ^= t;
q[i] ^= t;
}
}
function pack25519(o, n) {
var i, j, b;
var m = gf(), t = gf();
for (i = 0; i < 16; i++) t[i] = n[i];
car25519(t);
car25519(t);
car25519(t);
for (j = 0; j < 2; j++) {
m[0] = t[0] - 65517;
for (i = 1; i < 15; i++) {
m[i] = t[i] - 65535 - (m[i - 1] >> 16 & 1);
m[i - 1] &= 65535;
}
m[15] = t[15] - 32767 - (m[14] >> 16 & 1);
b = m[15] >> 16 & 1;
m[14] &= 65535;
sel25519(t, m, 1 - b);
}
for (i = 0; i < 16; i++) {
o[2 * i] = t[i] & 255;
o[2 * i + 1] = t[i] >> 8;
}
}
function neq25519(a, b) {
var c = new Uint8Array(32), d = new Uint8Array(32);
pack25519(c, a);
pack25519(d, b);
return crypto_verify_32(c, 0, d, 0);
}
function par25519(a) {
var d = new Uint8Array(32);
pack25519(d, a);
return d[0] & 1;
}
function unpack25519(o, n) {
var i;
for (i = 0; i < 16; i++) o[i] = n[2 * i] + (n[2 * i + 1] << 8);
o[15] &= 32767;
}
function A(o, a, b) {
for (var i = 0; i < 16; i++) o[i] = a[i] + b[i];
}
function Z(o, a, b) {
for (var i = 0; i < 16; i++) o[i] = a[i] - b[i];
}
function M(o, a, b) {
var v, c, t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7], b8 = b[8], b9 = b[9], b10 = b[10], b11 = b[11], b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15];
v = a[0];
t0 += v * b0;
t1 += v * b1;
t2 += v * b2;
t3 += v * b3;
t4 += v * b4;
t5 += v * b5;
t6 += v * b6;
t7 += v * b7;
t8 += v * b8;
t9 += v * b9;
t10 += v * b10;
t11 += v * b11;
t12 += v * b12;
t13 += v * b13;
t14 += v * b14;
t15 += v * b15;
v = a[1];
t1 += v * b0;
t2 += v * b1;
t3 += v * b2;
t4 += v * b3;
t5 += v * b4;
t6 += v * b5;
t7 += v * b6;
t8 += v * b7;
t9 += v * b8;
t10 += v * b9;
t11 += v * b10;
t12 += v * b11;
t13 += v * b12;
t14 += v * b13;
t15 += v * b14;
t16 += v * b15;
v = a[2];
t2 += v * b0;
t3 += v * b1;
t4 += v * b2;
t5 += v * b3;
t6 += v * b4;
t7 += v * b5;
t8 += v * b6;
t9 += v * b7;
t10 += v * b8;
t11 += v * b9;
t12 += v * b10;
t13 += v * b11;
t14 += v * b12;
t15 += v * b13;
t16 += v * b14;
t17 += v * b15;
v = a[3];
t3 += v * b0;
t4 += v * b1;
t5 += v * b2;
t6 += v * b3;
t7 += v * b4;
t8 += v * b5;
t9 += v * b6;
t10 += v * b7;
t11 += v * b8;
t12 += v * b9;
t13 += v * b10;
t14 += v * b11;
t15 += v * b12;
t16 += v * b13;
t17 += v * b14;
t18 += v * b15;
v = a[4];
t4 += v * b0;
t5 += v * b1;
t6 += v * b2;
t7 += v * b3;
t8 += v * b4;
t9 += v * b5;
t10 += v * b6;
t11 += v * b7;
t12 += v * b8;
t13 += v * b9;
t14 += v * b10;
t15 += v * b11;
t16 += v * b12;
t17 += v * b13;
t18 += v * b14;
t19 += v * b15;
v = a[5];
t5 += v * b0;
t6 += v * b1;
t7 += v * b2;
t8 += v * b3;
t9 += v * b4;
t10 += v * b5;
t11 += v * b6;
t12 += v * b7;
t13 += v * b8;
t14 += v * b9;
t15 += v * b10;
t16 += v * b11;
t17 += v * b12;
t18 += v * b13;
t19 += v * b14;
t20 += v * b15;
v = a[6];
t6 += v * b0;
t7 += v * b1;
t8 += v * b2;
t9 += v * b3;
t10 += v * b4;
t11 += v * b5;
t12 += v * b6;
t13 += v * b7;
t14 += v * b8;
t15 += v * b9;
t16 += v * b10;
t17 += v * b11;
t18 += v * b12;
t19 += v * b13;
t20 += v * b14;
t21 += v * b15;
v = a[7];
t7 += v * b0;
t8 += v * b1;
t9 += v * b2;
t10 += v * b3;
t11 += v * b4;
t12 += v * b5;
t13 += v * b6;
t14 += v * b7;
t15 += v * b8;
t16 += v * b9;
t17 += v * b10;
t18 += v * b11;
t19 += v * b12;
t20 += v * b13;
t21 += v * b14;
t22 += v * b15;
v = a[8];
t8 += v * b0;
t9 += v * b1;
t10 += v * b2;
t11 += v * b3;
t12 += v * b4;
t13 += v * b5;
t14 += v * b6;
t15 += v * b7;
t16 += v * b8;
t17 += v * b9;
t18 += v * b10;
t19 += v * b11;
t20 += v * b12;
t21 += v * b13;
t22 += v * b14;
t23 += v * b15;
v = a[9];
t9 += v * b0;
t10 += v * b1;
t11 += v * b2;
t12 += v * b3;
t13 += v * b4;
t14 += v * b5;
t15 += v * b6;
t16 += v * b7;
t17 += v * b8;
t18 += v * b9;
t19 += v * b10;
t20 += v * b11;
t21 += v * b12;
t22 += v * b13;
t23 += v * b14;
t24 += v * b15;
v = a[10];
t10 += v * b0;
t11 += v * b1;
t12 += v * b2;
t13 += v * b3;
t14 += v * b4;
t15 += v * b5;
t16 += v * b6;
t17 += v * b7;
t18 += v * b8;
t19 += v * b9;
t20 += v * b10;
t21 += v * b11;
t22 += v * b12;
t23 += v * b13;
t24 += v * b14;
t25 += v * b15;
v = a[11];
t11 += v * b0;
t12 += v * b1;
t13 += v * b2;
t14 += v * b3;
t15 += v * b4;
t16 += v * b5;
t17 += v * b6;
t18 += v * b7;
t19 += v * b8;
t20 += v * b9;
t21 += v * b10;
t22 += v * b11;
t23 += v * b12;
t24 += v * b13;
t25 += v * b14;
t26 += v * b15;
v = a[12];
t12 += v * b0;
t13 += v * b1;
t14 += v * b2;
t15 += v * b3;
t16 += v * b4;
t17 += v * b5;
t18 += v * b6;
t19 += v * b7;
t20 += v * b8;
t21 += v * b9;
t22 += v * b10;
t23 += v * b11;
t24 += v * b12;
t25 += v * b13;
t26 += v * b14;
t27 += v * b15;
v = a[13];
t13 += v * b0;
t14 += v * b1;
t15 += v * b2;
t16 += v * b3;
t17 += v * b4;
t18 += v * b5;
t19 += v * b6;
t20 += v * b7;
t21 += v * b8;
t22 += v * b9;
t23 += v * b10;
t24 += v * b11;
t25 += v * b12;
t26 += v * b13;
t27 += v * b14;
t28 += v * b15;
v = a[14];
t14 += v * b0;
t15 += v * b1;
t16 += v * b2;
t17 += v * b3;
t18 += v * b4;
t19 += v * b5;
t20 += v * b6;
t21 += v * b7;
t22 += v * b8;
t23 += v * b9;
t24 += v * b10;
t25 += v * b11;
t26 += v * b12;
t27 += v * b13;
t28 += v * b14;
t29 += v * b15;
v = a[15];
t15 += v * b0;
t16 += v * b1;
t17 += v * b2;
t18 += v * b3;
t19 += v * b4;
t20 += v * b5;
t21 += v * b6;
t22 += v * b7;
t23 += v * b8;
t24 += v * b9;
t25 += v * b10;
t26 += v * b11;
t27 += v * b12;
t28 += v * b13;
t29 += v * b14;
t30 += v * b15;
t0 += 38 * t16;
t1 += 38 * t17;
t2 += 38 * t18;
t3 += 38 * t19;
t4 += 38 * t20;
t5 += 38 * t21;
t6 += 38 * t22;
t7 += 38 * t23;
t8 += 38 * t24;
t9 += 38 * t25;
t10 += 38 * t26;
t11 += 38 * t27;
t12 += 38 * t28;
t13 += 38 * t29;
t14 += 38 * t30;
c = 1;
v = t0 + c + 65535;
c = Math.floor(v / 65536);
t0 = v - c * 65536;
v = t1 + c + 65535;
c = Math.floor(v / 65536);
t1 = v - c * 65536;
v = t2 + c + 65535;
c = Math.floor(v / 65536);
t2 = v - c * 65536;
v = t3 + c + 65535;
c = Math.floor(v / 65536);
t3 = v - c * 65536;
v = t4 + c + 65535;
c = Math.floor(v / 65536);
t4 = v - c * 65536;
v = t5 + c + 65535;
c = Math.floor(v / 65536);
t5 = v - c * 65536;
v = t6 + c + 65535;
c = Math.floor(v / 65536);
t6 = v - c * 65536;
v = t7 + c + 65535;
c = Math.floor(v / 65536);
t7 = v - c * 65536;
v = t8 + c + 65535;
c = Math.floor(v / 65536);
t8 = v - c * 65536;
v = t9 + c + 65535;
c = Math.floor(v / 65536);
t9 = v - c * 65536;
v = t10 + c + 65535;
c = Math.floor(v / 65536);
t10 = v - c * 65536;
v = t11 + c + 65535;
c = Math.floor(v / 65536);
t11 = v - c * 65536;
v = t12 + c + 65535;
c = Math.floor(v / 65536);
t12 = v - c * 65536;
v = t13 + c + 65535;
c = Math.floor(v / 65536);
t13 = v - c * 65536;
v = t14 + c + 65535;
c = Math.floor(v / 65536);
t14 = v - c * 65536;
v = t15 + c + 65535;
c = Math.floor(v / 65536);
t15 = v - c * 65536;
t0 += c - 1 + 37 * (c - 1);
c = 1;
v = t0 + c + 65535;
c = Math.floor(v / 65536);
t0 = v - c * 65536;
v = t1 + c + 65535;
c = Math.floor(v / 65536);
t1 = v - c * 65536;
v = t2 + c + 65535;
c = Math.floor(v / 65536);
t2 = v - c * 65536;
v = t3 + c + 65535;
c = Math.floor(v / 65536);
t3 = v - c * 65536;
v = t4 + c + 65535;
c = Math.floor(v / 65536);
t4 = v - c * 65536;
v = t5 + c + 65535;
c = Math.floor(v / 65536);
t5 = v - c * 65536;
v = t6 + c + 65535;
c = Math.floor(v / 65536);
t6 = v - c * 65536;
v = t7 + c + 65535;
c = Math.floor(v / 65536);
t7 = v - c * 65536;
v = t8 + c + 65535;
c = Math.floor(v / 65536);
t8 = v - c * 65536;
v = t9 + c + 65535;
c = Math.floor(v / 65536);
t9 = v - c * 65536;
v = t10 + c + 65535;
c = Math.floor(v / 65536);
t10 = v - c * 65536;
v = t11 + c + 65535;
c = Math.floor(v / 65536);
t11 = v - c * 65536;
v = t12 + c + 65535;
c = Math.floor(v / 65536);
t12 = v - c * 65536;
v = t13 + c + 65535;
c = Math.floor(v / 65536);
t13 = v - c * 65536;
v = t14 + c + 65535;
c = Math.floor(v / 65536);
t14 = v - c * 65536;
v = t15 + c + 65535;
c = Math.floor(v / 65536);
t15 = v - c * 65536;
t0 += c - 1 + 37 * (c - 1);
o[0] = t0;
o[1] = t1;
o[2] = t2;
o[3] = t3;
o[4] = t4;
o[5] = t5;
o[6] = t6;
o[7] = t7;
o[8] = t8;
o[9] = t9;
o[10] = t10;
o[11] = t11;
o[12] = t12;
o[13] = t13;
o[14] = t14;
o[15] = t15;
}
function S(o, a) {
M(o, a, a);
}
function inv25519(o, i) {
var c = gf();
var a;
for (a = 0; a < 16; a++) c[a] = i[a];
for (a = 253; a >= 0; a--) {
S(c, c);
if (a !== 2 && a !== 4) M(c, c, i);
}
for (a = 0; a < 16; a++) o[a] = c[a];
}
function pow2523(o, i) {
var c = gf();
var a;
for (a = 0; a < 16; a++) c[a] = i[a];
for (a = 250; a >= 0; a--) {
S(c, c);
if (a !== 1) M(c, c, i);
}
for (a = 0; a < 16; a++) o[a] = c[a];
}
function crypto_scalarmult(q, n, p) {
var z = new Uint8Array(32);
var x = new Float64Array(80), r, i;
var a = gf(), b = gf(), c = gf(), d = gf(), e = gf(), f = gf();
for (i = 0; i < 31; i++) z[i] = n[i];
z[31] = n[31] & 127 | 64;
z[0] &= 248;
unpack25519(x, p);
for (i = 0; i < 16; i++) {
b[i] = x[i];
d[i] = a[i] = c[i] = 0;
}
a[0] = d[0] = 1;
for (i = 254; i >= 0; --i) {
r = z[i >>> 3] >>> (i & 7) & 1;
sel25519(a, b, r);
sel25519(c, d, r);
A(e, a, c);
Z(a, a, c);
A(c, b, d);
Z(b, b, d);
S(d, e);
S(f, a);
M(a, c, a);
M(c, b, e);
A(e, a, c);
Z(a, a, c);
S(b, a);
Z(c, d, f);
M(a, c, _121665);
A(a, a, d);
M(c, c, a);
M(a, d, f);
M(d, b, x);
S(b, e);
sel25519(a, b, r);
sel25519(c, d, r);
}
for (i = 0; i < 16; i++) {
x[i + 16] = a[i];
x[i + 32] = c[i];
x[i + 48] = b[i];
x[i + 64] = d[i];
}
var x32 = x.subarray(32);
var x16 = x.subarray(16);
inv25519(x32, x32);
M(x16, x16, x32);
pack25519(q, x16);
return 0;
}
function crypto_scalarmult_base(q, n) {
return crypto_scalarmult(q, n, _9);
}
function crypto_box_keypair(y, x) {
randombytes(x, 32);
return crypto_scalarmult_base(y, x);
}
function crypto_box_beforenm(k, y, x) {
var s = new Uint8Array(32);
crypto_scalarmult(s, x, y);
return crypto_core_hsalsa20(k, _0, s, sigma);
}
var crypto_box_afternm = crypto_secretbox;
var crypto_box_open_afternm = crypto_secretbox_open;
function crypto_box(c, m, d, n, y, x) {
var k = new Uint8Array(32);
crypto_box_beforenm(k, y, x);
return crypto_box_afternm(c, m, d, n, k);
}
function crypto_box_open(m, c, d, n, y, x) {
var k = new Uint8Array(32);
crypto_box_beforenm(k, y, x);
return crypto_box_open_afternm(m, c, d, n, k);
}
var K = [ 1116352408, 3609767458, 1899447441, 602891725, 3049323471, 3964484399, 3921009573, 2173295548, 961987163, 4081628472, 1508970993, 3053834265, 2453635748, 2937671579, 2870763221, 3664609560, 3624381080, 2734883394, 310598401, 1164996542, 607225278, 1323610764, 1426881987, 3590304994, 1925078388, 4068182383, 2162078206, 991336113, 2614888103, 633803317, 3248222580, 3479774868, 3835390401, 2666613458, 4022224774, 944711139, 264347078, 2341262773, 604807628, 2007800933, 770255983, 1495990901, 1249150122, 1856431235, 1555081692, 3175218132, 1996064986, 2198950837, 2554220882, 3999719339, 2821834349, 766784016, 2952996808, 2566594879, 3210313671, 3203337956, 3336571891, 1034457026, 3584528711, 2466948901, 113926993, 3758326383, 338241895, 168717936, 666307205, 1188179964, 773529912, 1546045734, 1294757372, 1522805485, 1396182291, 2643833823, 1695183700, 2343527390, 1986661051, 1014477480, 2177026350, 1206759142, 2456956037, 344077627, 2730485921, 1290863460, 2820302411, 3158454273, 3259730800, 3505952657, 3345764771, 106217008, 3516065817, 3606008344, 3600352804, 1432725776, 4094571909, 1467031594, 275423344, 851169720, 430227734, 3100823752, 506948616, 1363258195, 659060556, 3750685593, 883997877, 3785050280, 958139571, 3318307427, 1322822218, 3812723403, 1537002063, 2003034995, 1747873779, 3602036899, 1955562222, 1575990012, 2024104815, 1125592928, 2227730452, 2716904306, 2361852424, 442776044, 2428436474, 593698344, 2756734187, 3733110249, 3204031479, 2999351573, 3329325298, 3815920427, 3391569614, 3928383900, 3515267271, 566280711, 3940187606, 3454069534, 4118630271, 4000239992, 116418474, 1914138554, 174292421, 2731055270, 289380356, 3203993006, 460393269, 320620315, 685471733, 587496836, 852142971, 1086792851, 1017036298, 365543100, 1126000580, 2618297676, 1288033470, 3409855158, 1501505948, 4234509866, 1607167915, 987167468, 1816402316, 1246189591 ];
function crypto_hashblocks_hl(hh, hl, m, n) {
var wh = new Int32Array(16), wl = new Int32Array(16), bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, th, tl, i, j, h, l, a, b, c, d;
var ah0 = hh[0], ah1 = hh[1], ah2 = hh[2], ah3 = hh[3], ah4 = hh[4], ah5 = hh[5], ah6 = hh[6], ah7 = hh[7], al0 = hl[0], al1 = hl[1], al2 = hl[2], al3 = hl[3], al4 = hl[4], al5 = hl[5], al6 = hl[6], al7 = hl[7];
var pos = 0;
while (n >= 128) {
for (i = 0; i < 16; i++) {
j = 8 * i + pos;
wh[i] = m[j + 0] << 24 | m[j + 1] << 16 | m[j + 2] << 8 | m[j + 3];
wl[i] = m[j + 4] << 24 | m[j + 5] << 16 | m[j + 6] << 8 | m[j + 7];
}
for (i = 0; i < 80; i++) {
bh0 = ah0;
bh1 = ah1;
bh2 = ah2;
bh3 = ah3;
bh4 = ah4;
bh5 = ah5;
bh6 = ah6;
bh7 = ah7;
bl0 = al0;
bl1 = al1;
bl2 = al2;
bl3 = al3;
bl4 = al4;
bl5 = al5;
bl6 = al6;
bl7 = al7;
h = ah7;
l = al7;
a = l & 65535;
b = l >>> 16;
c = h & 65535;
d = h >>> 16;
h = (ah4 >>> 14 | al4 << 32 - 14) ^ (ah4 >>> 18 | al4 << 32 - 18) ^ (al4 >>> 41 - 32 | ah4 << 32 - (41 - 32));
l = (al4 >>> 14 | ah4 << 32 - 14) ^ (al4 >>> 18 | ah4 << 32 - 18) ^ (ah4 >>> 41 - 32 | al4 << 32 - (41 - 32));
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
h = ah4 & ah5 ^ ~ah4 & ah6;
l = al4 & al5 ^ ~al4 & al6;
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
h = K[i * 2];
l = K[i * 2 + 1];
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
h = wh[i % 16];
l = wl[i % 16];
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
th = c & 65535 | d << 16;
tl = a & 65535 | b << 16;
h = th;
l = tl;
a = l & 65535;
b = l >>> 16;
c = h & 65535;
d = h >>> 16;
h = (ah0 >>> 28 | al0 << 32 - 28) ^ (al0 >>> 34 - 32 | ah0 << 32 - (34 - 32)) ^ (al0 >>> 39 - 32 | ah0 << 32 - (39 - 32));
l = (al0 >>> 28 | ah0 << 32 - 28) ^ (ah0 >>> 34 - 32 | al0 << 32 - (34 - 32)) ^ (ah0 >>> 39 - 32 | al0 << 32 - (39 - 32));
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
h = ah0 & ah1 ^ ah0 & ah2 ^ ah1 & ah2;
l = al0 & al1 ^ al0 & al2 ^ al1 & al2;
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
bh7 = c & 65535 | d << 16;
bl7 = a & 65535 | b << 16;
h = bh3;
l = bl3;
a = l & 65535;
b = l >>> 16;
c = h & 65535;
d = h >>> 16;
h = th;
l = tl;
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
bh3 = c & 65535 | d << 16;
bl3 = a & 65535 | b << 16;
ah1 = bh0;
ah2 = bh1;
ah3 = bh2;
ah4 = bh3;
ah5 = bh4;
ah6 = bh5;
ah7 = bh6;
ah0 = bh7;
al1 = bl0;
al2 = bl1;
al3 = bl2;
al4 = bl3;
al5 = bl4;
al6 = bl5;
al7 = bl6;
al0 = bl7;
if (i % 16 === 15) {
for (j = 0; j < 16; j++) {
h = wh[j];
l = wl[j];
a = l & 65535;
b = l >>> 16;
c = h & 65535;
d = h >>> 16;
h = wh[(j + 9) % 16];
l = wl[(j + 9) % 16];
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
th = wh[(j + 1) % 16];
tl = wl[(j + 1) % 16];
h = (th >>> 1 | tl << 32 - 1) ^ (th >>> 8 | tl << 32 - 8) ^ th >>> 7;
l = (tl >>> 1 | th << 32 - 1) ^ (tl >>> 8 | th << 32 - 8) ^ (tl >>> 7 | th << 32 - 7);
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
th = wh[(j + 14) % 16];
tl = wl[(j + 14) % 16];
h = (th >>> 19 | tl << 32 - 19) ^ (tl >>> 61 - 32 | th << 32 - (61 - 32)) ^ th >>> 6;
l = (tl >>> 19 | th << 32 - 19) ^ (th >>> 61 - 32 | tl << 32 - (61 - 32)) ^ (tl >>> 6 | th << 32 - 6);
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
wh[j] = c & 65535 | d << 16;
wl[j] = a & 65535 | b << 16;
}
}
}
h = ah0;
l = al0;
a = l & 65535;
b = l >>> 16;
c = h & 65535;
d = h >>> 16;
h = hh[0];
l = hl[0];
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[0] = ah0 = c & 65535 | d << 16;
hl[0] = al0 = a & 65535 | b << 16;
h = ah1;
l = al1;
a = l & 65535;
b = l >>> 16;
c = h & 65535;
d = h >>> 16;
h = hh[1];
l = hl[1];
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[1] = ah1 = c & 65535 | d << 16;
hl[1] = al1 = a & 65535 | b << 16;
h = ah2;
l = al2;
a = l & 65535;
b = l >>> 16;
c = h & 65535;
d = h >>> 16;
h = hh[2];
l = hl[2];
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[2] = ah2 = c & 65535 | d << 16;
hl[2] = al2 = a & 65535 | b << 16;
h = ah3;
l = al3;
a = l & 65535;
b = l >>> 16;
c = h & 65535;
d = h >>> 16;
h = hh[3];
l = hl[3];
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[3] = ah3 = c & 65535 | d << 16;
hl[3] = al3 = a & 65535 | b << 16;
h = ah4;
l = al4;
a = l & 65535;
b = l >>> 16;
c = h & 65535;
d = h >>> 16;
h = hh[4];
l = hl[4];
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[4] = ah4 = c & 65535 | d << 16;
hl[4] = al4 = a & 65535 | b << 16;
h = ah5;
l = al5;
a = l & 65535;
b = l >>> 16;
c = h & 65535;
d = h >>> 16;
h = hh[5];
l = hl[5];
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[5] = ah5 = c & 65535 | d << 16;
hl[5] = al5 = a & 65535 | b << 16;
h = ah6;
l = al6;
a = l & 65535;
b = l >>> 16;
c = h & 65535;
d = h >>> 16;
h = hh[6];
l = hl[6];
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[6] = ah6 = c & 65535 | d << 16;
hl[6] = al6 = a & 65535 | b << 16;
h = ah7;
l = al7;
a = l & 65535;
b = l >>> 16;
c = h & 65535;
d = h >>> 16;
h = hh[7];
l = hl[7];
a += l & 65535;
b += l >>> 16;
c += h & 65535;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[7] = ah7 = c & 65535 | d << 16;
hl[7] = al7 = a & 65535 | b << 16;
pos += 128;
n -= 128;
}
return n;
}
function crypto_hash(out, m, n) {
var hh = new Int32Array(8), hl = new Int32Array(8), x = new Uint8Array(256), i, b = n;
hh[0] = 1779033703;
hh[1] = 3144134277;
hh[2] = 1013904242;
hh[3] = 2773480762;
hh[4] = 1359893119;
hh[5] = 2600822924;
hh[6] = 528734635;
hh[7] = 1541459225;
hl[0] = 4089235720;
hl[1] = 2227873595;
hl[2] = 4271175723;
hl[3] = 1595750129;
hl[4] = 2917565137;
hl[5] = 725511199;
hl[6] = 4215389547;
hl[7] = 327033209;
crypto_hashblocks_hl(hh, hl, m, n);
n %= 128;
for (i = 0; i < n; i++) x[i] = m[b - n + i];
x[n] = 128;
n = 256 - 128 * (n < 112 ? 1 : 0);
x[n - 9] = 0;
ts64(x, n - 8, b / 536870912 | 0, b << 3);
crypto_hashblocks_hl(hh, hl, x, n);
for (i = 0; i < 8; i++) ts64(out, 8 * i, hh[i], hl[i]);
return 0;
}
function add(p, q) {
var a = gf(), b = gf(), c = gf(), d = gf(), e = gf(), f = gf(), g = gf(), h = gf(), t = gf();
Z(a, p[1], p[0]);
Z(t, q[1], q[0]);
M(a, a, t);
A(b, p[0], p[1]);
A(t, q[0], q[1]);
M(b, b, t);
M(c, p[3], q[3]);
M(c, c, D2);
M(d, p[2], q[2]);
A(d, d, d);
Z(e, b, a);
Z(f, d, c);
A(g, d, c);
A(h, b, a);
M(p[0], e, f);
M(p[1], h, g);
M(p[2], g, f);
M(p[3], e, h);
}
function cswap(p, q, b) {
var i;
for (i = 0; i < 4; i++) {
sel25519(p[i], q[i], b);
}
}
function pack(r, p) {
var tx = gf(), ty = gf(), zi = gf();
inv25519(zi, p[2]);
M(tx, p[0], zi);
M(ty, p[1], zi);
pack25519(r, ty);
r[31] ^= par25519(tx) << 7;
}
function scalarmult(p, q, s) {
var b, i;
set25519(p[0], gf0);
set25519(p[1], gf1);
set25519(p[2], gf1);
set25519(p[3], gf0);
for (i = 255; i >= 0; --i) {
b = s[i / 8 | 0] >> (i & 7) & 1;
cswap(p, q, b);
add(q, p);
add(p, p);
cswap(p, q, b);
}
}
function scalarbase(p, s) {
var q = [ gf(), gf(), gf(), gf() ];
set25519(q[0], X);
set25519(q[1], Y);
set25519(q[2], gf1);
M(q[3], X, Y);
scalarmult(p, q, s);
}
function crypto_sign_keypair(pk, sk, seeded) {
var d = new Uint8Array(64);
var p = [ gf(), gf(), gf(), gf() ];
var i;
if (!seeded) randombytes(sk, 32);
crypto_hash(d, sk, 32);
d[0] &= 248;
d[31] &= 127;
d[31] |= 64;
scalarbase(p, d);
pack(pk, p);
for (i = 0; i < 32; i++) sk[i + 32] = pk[i];
return 0;
}
var L = new Float64Array([ 237, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16 ]);
function modL(r, x) {
var carry, i, j, k;
for (i = 63; i >= 32; --i) {
carry = 0;
for (j = i - 32, k = i - 12; j < k; ++j) {
x[j] += carry - 16 * x[i] * L[j - (i - 32)];
carry = x[j] + 128 >> 8;
x[j] -= carry * 256;
}
x[j] += carry;
x[i] = 0;
}
carry = 0;
for (j = 0; j < 32; j++) {
x[j] += carry - (x[31] >> 4) * L[j];
carry = x[j] >> 8;
x[j] &= 255;
}
for (j = 0; j < 32; j++) x[j] -= carry * L[j];
for (i = 0; i < 32; i++) {
x[i + 1] += x[i] >> 8;
r[i] = x[i] & 255;
}
}
function reduce(r) {
var x = new Float64Array(64), i;
for (i = 0; i < 64; i++) x[i] = r[i];
for (i = 0; i < 64; i++) r[i] = 0;
modL(r, x);
}
function crypto_sign(sm, m, n, sk) {
var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64);
var i, j, x = new Float64Array(64);
var p = [ gf(), gf(), gf(), gf() ];
crypto_hash(d, sk, 32);
d[0] &= 248;
d[31] &= 127;
d[31] |= 64;
var smlen = n + 64;
for (i = 0; i < n; i++) sm[64 + i] = m[i];
for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i];
crypto_hash(r, sm.subarray(32), n + 32);
reduce(r);
scalarbase(p, r);
pack(sm, p);
for (i = 32; i < 64; i++) sm[i] = sk[i];
crypto_hash(h, sm, n + 64);
reduce(h);
for (i = 0; i < 64; i++) x[i] = 0;
for (i = 0; i < 32; i++) x[i] = r[i];
for (i = 0; i < 32; i++) {
for (j = 0; j < 32; j++) {
x[i + j] += h[i] * d[j];
}
}
modL(sm.subarray(32), x);
return smlen;
}
function unpackneg(r, p) {
var t = gf(), chk = gf(), num = gf(), den = gf(), den2 = gf(), den4 = gf(), den6 = gf();
set25519(r[2], gf1);
unpack25519(r[1], p);
S(num, r[1]);
M(den, num, D);
Z(num, num, r[2]);
A(den, r[2], den);
S(den2, den);
S(den4, den2);
M(den6, den4, den2);
M(t, den6, num);
M(t, t, den);
pow2523(t, t);
M(t, t, num);
M(t, t, den);
M(t, t, den);
M(r[0], t, den);
S(chk, r[0]);
M(chk, chk, den);
if (neq25519(chk, num)) M(r[0], r[0], I);
S(chk, r[0]);
M(chk, chk, den);
if (neq25519(chk, num)) return -1;
if (par25519(r[0]) === p[31] >> 7) Z(r[0], gf0, r[0]);
M(r[3], r[0], r[1]);
return 0;
}
function crypto_sign_open(m, sm, n, pk) {
var i, mlen;
var t = new Uint8Array(32), h = new Uint8Array(64);
var p = [ gf(), gf(), gf(), gf() ], q = [ gf(), gf(), gf(), gf() ];
mlen = -1;
if (n < 64) return -1;
if (unpackneg(q, pk)) return -1;
for (i = 0; i < n; i++) m[i] = sm[i];
for (i = 0; i < 32; i++) m[i + 32] = pk[i];
crypto_hash(h, m, n);
reduce(h);
scalarmult(p, q, h);
scalarbase(q, sm.subarray(32));
add(p, q);
pack(t, p);
n -= 64;
if (crypto_verify_32(sm, 0, t, 0)) {
for (i = 0; i < n; i++) m[i] = 0;
return -1;
}
for (i = 0; i < n; i++) m[i] = sm[i + 64];
mlen = n;
return mlen;
}
var crypto_secretbox_KEYBYTES = 32, crypto_secretbox_NONCEBYTES = 24, crypto_secretbox_ZEROBYTES = 32, crypto_secretbox_BOXZEROBYTES = 16, crypto_scalarmult_BYTES = 32, crypto_scalarmult_SCALARBYTES = 32, crypto_box_PUBLICKEYBYTES = 32, crypto_box_SECRETKEYBYTES = 32, crypto_box_BEFORENMBYTES = 32, crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES, crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES, crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES, crypto_sign_BYTES = 64, crypto_sign_PUBLICKEYBYTES = 32, crypto_sign_SECRETKEYBYTES = 64, crypto_sign_SEEDBYTES = 32, crypto_hash_BYTES = 64;
nacl.lowlevel = {
crypto_core_hsalsa20,
crypto_stream_xor,
crypto_stream,
crypto_stream_salsa20_xor,
crypto_stream_salsa20,
crypto_onetimeauth,
crypto_onetimeauth_verify,
crypto_verify_16,
crypto_verify_32,
crypto_secretbox,
crypto_secretbox_open,
crypto_scalarmult,
crypto_scalarmult_base,
crypto_box_beforenm,
crypto_box_afternm,
crypto_box,
crypto_box_open,
crypto_box_keypair,
crypto_hash,
crypto_sign,
crypto_sign_keypair,
crypto_sign_open,
crypto_secretbox_KEYBYTES,
crypto_secretbox_NONCEBYTES,
crypto_secretbox_ZEROBYTES,
crypto_secretbox_BOXZEROBYTES,
crypto_scalarmult_BYTES,
crypto_scalarmult_SCALARBYTES,
crypto_box_PUBLICKEYBYTES,
crypto_box_SECRETKEYBYTES,
crypto_box_BEFORENMBYTES,
crypto_box_NONCEBYTES,
crypto_box_ZEROBYTES,
crypto_box_BOXZEROBYTES,
crypto_sign_BYTES,
crypto_sign_PUBLICKEYBYTES,
crypto_sign_SECRETKEYBYTES,
crypto_sign_SEEDBYTES,
crypto_hash_BYTES
};
function checkLengths(k, n) {
if (k.length !== crypto_secretbox_KEYBYTES) throw new Error("bad key size");
if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error("bad nonce size");
}
function checkBoxLengths(pk, sk) {
if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error("bad public key size");
if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error("bad secret key size");
}
function checkArrayTypes() {
var type = {}.toString, t;
for (var i = 0; i < arguments.length; i++) {
if ((t = type.call(arguments[i])) !== "[object Uint8Array]") throw new TypeError("unexpected type " + t + ", use Uint8Array");
}
}
nacl.util = {};
nacl.util.decodeUTF8 = function(s) {
var i, d = unescape(encodeURIComponent(s)), b = new Uint8Array(d.length);
for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i);
return b;
};
nacl.util.encodeUTF8 = function(arr) {
var i, s = [];
for (i = 0; i < arr.length; i++) s.push(String.fromCharCode(arr[i]));
return decodeURIComponent(escape(s.join("")));
};
nacl.util.encodeBase64 = function(arr) {
if (typeof btoa === "undefined") {
return new Buffer(arr).toString("base64");
} else {
var i, s = [], len = arr.length;
for (i = 0; i < len; i++) s.push(String.fromCharCode(arr[i]));
return btoa(s.join(""));
}
};
nacl.util.decodeBase64 = function(s) {
if (typeof atob === "undefined") {
return new Uint8Array(Array.prototype.slice.call(new Buffer(s, "base64"), 0));
} else {
var i, d = atob(s), b = new Uint8Array(d.length);
for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i);
return b;
}
};
nacl.randomBytes = function(n) {
var b = new Uint8Array(n);
randombytes(b, n);
return b;
};
nacl.secretbox = function(msg, nonce, key) {
checkArrayTypes(msg, nonce, key);
checkLengths(key, nonce);
var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length);
var c = new Uint8Array(m.length);
for (var i = 0; i < msg.length; i++) m[i + crypto_secretbox_ZEROBYTES] = msg[i];
crypto_secretbox(c, m, m.length, nonce, key);
return c.subarray(crypto_secretbox_BOXZEROBYTES);
};
nacl.secretbox.open = function(box, nonce, key) {
checkArrayTypes(box, nonce, key);
checkLengths(key, nonce);
var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length);
var m = new Uint8Array(c.length);
for (var i = 0; i < box.length; i++) c[i + crypto_secretbox_BOXZEROBYTES] = box[i];
if (c.length < 32) return false;
if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return false;
return m.subarray(crypto_secretbox_ZEROBYTES);
};
nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES;
nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES;
nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES;
nacl.scalarMult = function(n, p) {
checkArrayTypes(n, p);
if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error("bad n size");
if (p.length !== crypto_scalarmult_BYTES) throw new Error("bad p size");
var q = new Uint8Array(crypto_scalarmult_BYTES);
crypto_scalarmult(q, n, p);
return q;
};
nacl.scalarMult.base = function(n) {
checkArrayTypes(n);
if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error("bad n size");
var q = new Uint8Array(crypto_scalarmult_BYTES);
crypto_scalarmult_base(q, n);
return q;
};
nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES;
nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES;
nacl.box = function(msg, nonce, publicKey, secretKey) {
var k = nacl.box.before(publicKey, secretKey);
return nacl.secretbox(msg, nonce, k);
};
nacl.box.before = function(publicKey, secretKey) {
checkArrayTypes(publicKey, secretKey);
checkBoxLengths(publicKey, secretKey);
var k = new Uint8Array(crypto_box_BEFORENMBYTES);
crypto_box_beforenm(k, publicKey, secretKey);
return k;
};
nacl.box.after = nacl.secretbox;
nacl.box.open = function(msg, nonce, publicKey, secretKey) {
var k = nacl.box.before(publicKey, secretKey);
return nacl.secretbox.open(msg, nonce, k);
};
nacl.box.open.after = nacl.secretbox.open;
nacl.box.keyPair = function() {
var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
var sk = new Uint8Array(crypto_box_SECRETKEYBYTES);
crypto_box_keypair(pk, sk);
return {
publicKey: pk,
secretKey: sk
};
};
nacl.box.keyPair.fromSecretKey = function(secretKey) {
checkArrayTypes(secretKey);
if (secretKey.length !== crypto_box_SECRETKEYBYTES) throw new Error("bad secret key size");
var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
crypto_scalarmult_base(pk, secretKey);
return {
publicKey: pk,
secretKey: new Uint8Array(secretKey)
};
};
nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES;
nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES;
nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES;
nacl.box.nonceLength = crypto_box_NONCEBYTES;
nacl.box.overheadLength = nacl.secretbox.overheadLength;
nacl.sign = function(msg, secretKey) {
checkArrayTypes(msg, secretKey);
if (secretKey.length !== crypto_sign_SECRETKEYBYTES) throw new Error("bad secret key size");
var signedMsg = new Uint8Array(crypto_sign_BYTES + msg.length);
crypto_sign(signedMsg, msg, msg.length, secretKey);
return signedMsg;
};
nacl.sign.open = function(signedMsg, publicKey) {
if (arguments.length !== 2) throw new Error("nacl.sign.open accepts 2 arguments; did you mean to use nacl.sign.detached.verify?");
checkArrayTypes(signedMsg, publicKey);
if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) throw new Error("bad public key size");
var tmp = new Uint8Array(signedMsg.length);
var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey);
if (mlen < 0) return null;
var m = new Uint8Array(mlen);
for (var i = 0; i < m.length; i++) m[i] = tmp[i];
return m;
};
nacl.sign.detached = function(msg, secretKey) {
var signedMsg = nacl.sign(msg, secretKey);
var sig = new Uint8Array(crypto_sign_BYTES);
for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i];
return sig;
};
nacl.sign.detached.verify = function(msg, sig, publicKey) {
checkArrayTypes(msg, sig, publicKey);
if (sig.length !== crypto_sign_BYTES) throw new Error("bad signature size");
if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) throw new Error("bad public key size");
var sm = new Uint8Array(crypto_sign_BYTES + msg.length);
var m = new Uint8Array(crypto_sign_BYTES + msg.length);
var i;
for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i];
for (i = 0; i < msg.length; i++) sm[i + crypto_sign_BYTES] = msg[i];
return crypto_sign_open(m, sm, sm.length, publicKey) >= 0;
};
nacl.sign.keyPair = function() {
var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
crypto_sign_keypair(pk, sk);
return {
publicKey: pk,
secretKey: sk
};
};
nacl.sign.keyPair.fromSecretKey = function(secretKey) {
checkArrayTypes(secretKey);
if (secretKey.length !== crypto_sign_SECRETKEYBYTES) throw new Error("bad secret key size");
var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32 + i];
return {
publicKey: pk,
secretKey: new Uint8Array(secretKey)
};
};
nacl.sign.keyPair.fromSeed = function(seed) {
checkArrayTypes(seed);
if (seed.length !== crypto_sign_SEEDBYTES) throw new Error("bad seed size");
var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
for (var i = 0; i < 32; i++) sk[i] = seed[i];
crypto_sign_keypair(pk, sk, true);
return {
publicKey: pk,
secretKey: sk
};
};
nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES;
nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES;
nacl.sign.seedLength = crypto_sign_SEEDBYTES;
nacl.sign.signatureLength = crypto_sign_BYTES;
nacl.hash = function(msg) {
checkArrayTypes(msg);
var h = new Uint8Array(crypto_hash_BYTES);
crypto_hash(h, msg, msg.length);
return h;
};
nacl.hash.hashLength = crypto_hash_BYTES;
nacl.verify = function(x, y) {
checkArrayTypes(x, y);
if (x.length === 0 || y.length === 0) return false;
if (x.length !== y.length) return false;
return vn(x, 0, y, 0, x.length) === 0 ? true : false;
};
nacl.setPRNG = function(fn) {
randombytes = fn;
};
(function() {
var crypto;
if (typeof window !== "undefined") {
if (window.crypto && window.crypto.getRandomValues) {
crypto = window.crypto;
} else if (window.msCrypto && window.msCrypto.getRandomValues) {
crypto = window.msCrypto;
}
if (crypto) {
nacl.setPRNG((function(x, n) {
var i, v = new Uint8Array(n);
crypto.getRandomValues(v);
for (i = 0; i < n; i++) x[i] = v[i];
}));
}
} else if (typeof commonjsRequire !== "undefined") {
crypto = require("crypto");
if (crypto) {
nacl.setPRNG((function(x, n) {
var i, v = crypto.randomBytes(n);
for (i = 0; i < n; i++) x[i] = v[i];
}));
}
}
})();
})(module.exports ? module.exports : window.nacl = window.nacl || {});
})(naclFast);
return naclFast.exports;
}
var hasRequiredCrypto;
function requireCrypto() {
if (hasRequiredCrypto) return crypto.exports;
hasRequiredCrypto = 1;
(function(module) {
(function() {
var factory = function(Nacl) {
var Crypto = {
Nacl
};
var encodeBase64 = Nacl.util.encodeBase64;
var decodeBase64 = Nacl.util.decodeBase64;
var decodeUTF8 = Nacl.util.decodeUTF8;
var encodeUTF8 = Nacl.util.encodeUTF8;
var encodeHex = function(bytes) {
var hexString = "";
for (var i = 0; i < bytes.length; i++) {
if (bytes[i] < 16) {
hexString += "0";
}
hexString += bytes[i].toString(16);
}
return hexString;
};
var encryptStr = function(str, key) {
var array = decodeUTF8(str);
var nonce = Nacl.randomBytes(24);
var packed = Nacl.secretbox(array, nonce, key);
if (!packed) {
throw new Error;
}
return encodeBase64(nonce) + "|" + encodeBase64(packed);
};
var decryptStr = function(str, key) {
var arr = str.split("|");
if (arr.length !== 2) {
throw new Error;
}
var nonce = decodeBase64(arr[0]);
var packed = decodeBase64(arr[1]);
var unpacked = Nacl.secretbox.open(packed, nonce, key);
if (!unpacked) {
throw new Error;
}
return encodeUTF8(unpacked);
};
var encrypt = Crypto.encrypt = function(msg, key) {
return encryptStr(msg, key);
};
var decrypt = Crypto.decrypt = function(msg, key) {
return decryptStr(msg, key);
};
var parseKey = Crypto.parseKey = function(str) {
try {
var array = decodeBase64(str);
var hash = Nacl.hash(array);
var lk = hash.subarray(32);
return {
lookupKey: lk,
cryptKey: hash.subarray(0, 32),
channel: encodeBase64(lk).substring(0, 10)
};
} catch (err) {
console.error("[chainpad-crypto.parseKey] invalid string supplied");
throw err;
}
};
var rand64 = Crypto.rand64 = function(bytes) {
return encodeBase64(Nacl.randomBytes(bytes));
};
Crypto.genKey = function() {
return rand64(18);
};
var b64Encode = function(bytes) {
return encodeBase64(bytes).replace(/\//g, "-").replace(/=+$/g, "");
};
var b64Decode = function(str) {
return decodeBase64(str.replace(/\-/g, "/"));
};
Crypto.b64RemoveSlashes = function(str) {
return str.replace(/\//g, "-");
};
Crypto.b64AddSlashes = function(str) {
return str.replace(/\-/g, "/");
};
Crypto.createEncryptor = function(input) {
var key;
if (typeof input === "object") {
var out = {};
key = input.cryptKey;
if (!key) {
throw new Error("NO_DECRYPTION_KEY_PROVIDED");
}
if (input.signKey) {
var signKey = decodeBase64(input.signKey);
out.encrypt = function(msg) {
return encodeBase64(Nacl.sign(decodeUTF8(encrypt(msg, key)), signKey));
};
}
out.decrypt = function(msg, validateKey, skipCheck) {
if (!validateKey && !skipCheck) {
throw new Error("UNSUPPORTED_DECRYPTION_CONFIGURATION");
}
if (validateKey === true && !skipCheck) {
console.error("UNEXPECTED_CONFIGURATION");
}
var validated = skipCheck || typeof validateKey !== "string" ? decodeBase64(msg).subarray(64) : Nacl.sign.open(decodeBase64(msg), decodeBase64(validateKey));
if (!validated) {
return;
}
return decrypt(encodeUTF8(validated), key);
};
return out;
}
key = parseKey(input).cryptKey;
return {
encrypt: function(msg) {
return encrypt(msg, key);
},
decrypt: function(msg) {
return decrypt(msg, key);
}
};
};
Crypto.createEditCryptor = function(keyStr, seed) {
try {
if (!keyStr) {
if (seed && seed.length !== 18) {
throw new Error("expected supplied seed to have length of 18");
} else if (!seed) {
seed = Nacl.randomBytes(18);
}
keyStr = encodeBase64(seed);
}
var hash = Nacl.hash(decodeBase64(keyStr));
var signKp = Nacl.sign.keyPair.fromSeed(hash.subarray(0, 32));
var cryptKey = hash.subarray(32, 64);
return {
editKeyStr: keyStr,
signKey: encodeBase64(signKp.secretKey),
validateKey: encodeBase64(signKp.publicKey),
cryptKey,
viewKeyStr: b64Encode(cryptKey)
};
} catch (err) {
console.error("[chainpad-crypto.createEditCryptor] invalid string supplied");
throw err;
}
};
Crypto.createViewCryptor = function(cryptKeyStr) {
try {
if (!cryptKeyStr) {
throw new Error("Cannot open a new pad in read-only mode!");
}
return {
cryptKey: decodeBase64(cryptKeyStr),
viewKeyStr: cryptKeyStr
};
} catch (err) {
console.error("[chainpad-crypto.createViewCryptor] invalid string supplied");
throw err;
}
};
var createViewCryptor2 = Crypto.createViewCryptor2 = function(viewKeyStr, password) {
try {
if (!viewKeyStr) {
throw new Error("Cannot open a new pad in read-only mode!");
}
var seed = b64Decode(viewKeyStr);
var superSeed = seed;
if (password) {
var pwKey = decodeUTF8(password);
superSeed = new Uint8Array(seed.length + pwKey.length);
superSeed.set(pwKey);
superSeed.set(seed, pwKey.length);
}
var hash = Nacl.hash(superSeed);
var chanId = hash.subarray(0, 16);
var cryptKey = hash.subarray(16, 48);
var signKp2 = Nacl.sign.keyPair.fromSeed(hash.subarray(32, 64));
return {
viewKeyStr,
cryptKey,
chanId: b64Encode(chanId),
secondarySignKey: encodeBase64(signKp2.secretKey),
secondaryValidateKey: encodeBase64(signKp2.publicKey)
};
} catch (err) {
console.error("[chainpad-crypto.createViewCryptor2] invalid string supplied");
throw err;
}
};
Crypto.createEditCryptor2 = function(keyStr, seed, password) {
try {
if (!keyStr) {
if (seed && seed.length !== 18) {
throw new Error("expected supplied seed to have length of 18");
} else if (!seed) {
seed = Nacl.randomBytes(18);
}
keyStr = b64Encode(seed);
}
if (!seed) {
seed = b64Decode(keyStr);
}
var superSeed = seed;
if (password) {
var pwKey = decodeUTF8(password);
superSeed = new Uint8Array(seed.length + pwKey.length);
superSeed.set(pwKey);
superSeed.set(seed, pwKey.length);
}
var hash = Nacl.hash(superSeed);
var signKp = Nacl.sign.keyPair.fromSeed(hash.subarray(0, 32));
var secondary = Nacl.hash(signKp.secretKey).subarray(0, Nacl.secretbox.keyLength);
var seed2 = hash.subarray(32, 64);
var viewKeyStr = b64Encode(seed2);
var viewCryptor = createViewCryptor2(viewKeyStr, password);
return {
editKeyStr: keyStr,
viewKeyStr,
signKey: encodeBase64(signKp.secretKey),
validateKey: encodeBase64(signKp.publicKey),
cryptKey: viewCryptor.cryptKey,
secondaryKey: encodeBase64(secondary),
chanId: viewCryptor.chanId,
secondarySignKey: viewCryptor.secondarySignKey,
secondaryValidateKey: viewCryptor.secondaryValidateKey
};
} catch (err) {
console.error("[chainpad-crypto.createEditCryptor2] invalid string supplied");
throw err;
}
};
Crypto.createFileCryptor2 = function(keyStr, password) {
try {
var seed;
if (!keyStr) {
seed = Nacl.randomBytes(18);
keyStr = b64Encode(seed);
}
if (!seed) {
seed = b64Decode(keyStr);
}
var superSeed = seed;
if (password) {
var pwKey = decodeUTF8(password);
superSeed = new Uint8Array(seed.length + pwKey.length);
superSeed.set(pwKey);
superSeed.set(seed, pwKey.length);
}
var hash = Nacl.hash(superSeed);
var chanId = hash.subarray(0, 24);
var cryptKey = hash.subarray(24, 56);
return {
fileKeyStr: keyStr,
cryptKey,
chanId: b64Encode(chanId)
};
} catch (err) {
console.error("[chainpad-crypto.createFileCryptor2] invalid string supplied");
throw err;
}
};
var Curve = Crypto.Curve = {};
var u8_concat = function(A) {
var length = 0;
A.forEach((function(a) {
length += a.length;
}));
var total = new Uint8Array(length);
var offset = 0;
A.forEach((function(a) {
total.set(a, offset);
offset += a.length;
}));
return total;
};
Curve.encrypt = function(message, secret) {
var buffer = decodeUTF8(message);
var nonce = Nacl.randomBytes(24);
var box = Nacl.box.after(buffer, nonce, secret);
return encodeBase64(nonce) + "|" + encodeBase64(box);
};
Curve.decrypt = function(packed, secret) {
var unpacked = packed.split("|");
var nonce = decodeBase64(unpacked[0]);
var box = decodeBase64(unpacked[1]);
var message = Nacl.box.open.after(box, nonce, secret);
if (message === false) {
return null;
}
return encodeUTF8(message);
};
Curve.signAndEncrypt = function(msg, cryptKey, signKey) {
var packed = Curve.encrypt(msg, cryptKey);
return encodeBase64(Nacl.sign(decodeUTF8(packed), signKey));
};
Curve.openSigned = function(msg, cryptKey) {
var content = decodeBase64(msg).subarray(64);
return Curve.decrypt(encodeUTF8(content), cryptKey);
};
Curve.deriveKeys = function(theirs, mine) {
try {
var pub = decodeBase64(theirs);
var secret = decodeBase64(mine);
var sharedSecret = Nacl.box.before(pub, secret);
var salt = decodeUTF8("CryptPad.signingKeyGenerationSalt");
var hash = Nacl.hash(u8_concat([ salt, sharedSecret ]));
var signKp = Nacl.sign.keyPair.fromSeed(hash.subarray(0, 32));
var cryptKey = hash.subarray(32, 64);
return {
cryptKey: encodeBase64(cryptKey),
signKey: encodeBase64(signKp.secretKey),
validateKey: encodeBase64(signKp.publicKey)
};
} catch (e) {
console.error("invalid keys or other problem deriving keys");
console.error(e);
return null;
}
};
Curve.createEncryptor = function(keys) {
if (!keys || typeof keys !== "object") {
return void console.error("invalid input for createEncryptor");
}
var cryptKey = decodeBase64(keys.cryptKey);
var signKey = decodeBase64(keys.signKey);
var validateKey = decodeBase64(keys.validateKey);
return {
encrypt: function(msg) {
return Curve.signAndEncrypt(msg, cryptKey, signKey);
},
decrypt: function(packed) {
return Curve.openSigned(packed, cryptKey, validateKey);
}
};
};
var u8_slice = function(A, start, end) {
return new Uint8Array(Array.prototype.slice.call(A, start, end));
};
var Mailbox = Crypto.Mailbox = {};
var asymmetric_encrypt = function(u8_plain, keys) {
var u8_nonce = Nacl.randomBytes(Nacl.box.nonceLength);
var u8_cipher = Nacl.box(u8_plain, u8_nonce, keys.their_public, keys.my_private);
var u8_bundle = u8_concat([ u8_nonce, keys.my_public, u8_cipher ]);
return u8_bundle;
};
var asymmetric_decrypt = function(u8_bundle, keys) {
var u8_nonce = u8_slice(u8_bundle, 0, Nacl.box.nonceLength);
var u8_sender_public = u8_slice(u8_bundle, Nacl.box.nonceLength, Nacl.box.nonceLength + Nacl.box.publicKeyLength);
var u8_cipher = u8_slice(u8_bundle, Nacl.box.nonceLength + Nacl.box.publicKeyLength);
var u8_plain = Nacl.box.open(u8_cipher, u8_nonce, keys.their_public || u8_sender_public, keys.my_private);
if (!u8_plain) {
throw new Error("E_DECRYPTION_FAILURE");
}
return {
content: u8_plain,
author: u8_sender_public
};
};
var sealSecretLetter = Mailbox.sealSecretLetter = function(plain, keys) {
var u8_plain = decodeUTF8(plain);
var u8_letter = asymmetric_encrypt(u8_plain, {
their_public: keys.their_public,
my_private: keys.my_private,
my_public: keys.my_public
});
var u8_ephemeral_keypair = keys.ephemeral_keypair || Nacl.box.keyPair();
var u8_sealed = asymmetric_encrypt(u8_letter, {
their_public: keys.their_public,
my_private: u8_ephemeral_keypair.secretKey,
my_public: u8_ephemeral_keypair.publicKey
});
if (keys.signingKey) {
u8_sealed = Nacl.sign(u8_sealed, keys.signingKey);
}
return encodeBase64(u8_sealed);
};
Mailbox.openOwnSecretLetter = function(b64_bundle, keys) {
var u8_bundle = decodeBase64(b64_bundle);
if (keys.validateKey) {
u8_bundle = u8_bundle.subarray(64);
}
var letter = asymmetric_decrypt(u8_bundle, {
my_private: keys.ephemeral_private,
their_public: keys.their_public
});
var u8_plain = asymmetric_decrypt(letter.content, {
my_private: keys.my_private,
their_public: keys.their_public
});
return {
content: encodeUTF8(u8_plain.content),
author: encodeBase64(u8_plain.author)
};
};
var openSecretLetter = Mailbox.openSecretLetter = function(b64_bundle, keys) {
var u8_bundle = decodeBase64(b64_bundle);
if (keys.validateKey) {
u8_bundle = u8_bundle.subarray(64);
}
var letter = asymmetric_decrypt(u8_bundle, {
my_private: keys.my_private
});
var u8_plain = asymmetric_decrypt(letter.content, {
my_private: keys.my_private
});
return {
content: encodeUTF8(u8_plain.content),
author: encodeBase64(u8_plain.author)
};
};
Mailbox.createEncryptor = function(keys) {
if (!keys || typeof keys !== "object") {
return void console.error("invalid Mailbox.createEncryptor keys");
}
[ "curvePublic", "curvePrivate" ].forEach((function(k) {
if (typeof keys[k] !== "string") {
console.log(k);
throw new Error("Expected key was not present");
}
}));
var u8_my_private = decodeBase64(keys.curvePrivate);
var u8_my_public = decodeBase64(keys.curvePublic);
var signingKey = keys.signingKey ? decodeBase64(keys.signingKey) : undefined;
var validateKey = keys.validateKey ? decodeBase64(keys.validateKey) : undefined;
return {
encrypt: function(plain, recipient) {
var u8_their_public = decodeBase64(recipient);
try {
var sealed = sealSecretLetter(plain, {
signingKey,
ephemeral_keypair: keys.ephemeral_keypair,
their_public: u8_their_public,
my_private: u8_my_private,
my_public: u8_my_public
});
return sealed;
} catch (e) {
console.error(e);
return null;
}
},
decrypt: function(cipher) {
try {
return openSecretLetter(cipher, {
validateKey,
my_private: u8_my_private
});
} catch (e) {
console.error(e);
return null;
}
}
};
};
var Team = Crypto.Team = {};
var encryptForTeam = function(plain, keys) {
var u8_plain = decodeUTF8(plain);
var u8_inner = asymmetric_encrypt(u8_plain, {
their_public: keys.team_curve_public,
my_private: keys.my_curve_private,
my_public: keys.my_curve_public
});
var u8_ephemeral_keypair = Nacl.box.keyPair();
var u8_outer = asymmetric_encrypt(u8_inner, {
their_public: keys.team_curve_public,
my_private: u8_ephemeral_keypair.secretKey,
my_public: u8_ephemeral_keypair.publicKey
});
return encodeBase64(Nacl.sign(u8_outer, keys.team_ed_private));
};
var decryptForTeam = function(b64_bundle, keys, skipValidation) {
var u8_bundle = decodeBase64(b64_bundle);
var u8_outer;
if (skipValidation === true) {
u8_outer = u8_slice(u8_bundle, 64);
} else {
u8_outer = Nacl.sign.open(u8_bundle, keys.team_ed_public);
}
if (u8_outer === null) {
throw new Error("E_VALIDATION_FAILURE");
}
var inner = asymmetric_decrypt(u8_outer, {
my_private: keys.team_curve_private
});
var u8_plain = asymmetric_decrypt(inner.content, {
my_private: keys.team_curve_private
});
return {
content: encodeUTF8(u8_plain.content),
author: encodeBase64(u8_plain.author)
};
};
var team_key_map = {
teamCurvePublic: "team_curve_public",
teamCurvePrivate: "team_curve_private",
myCurvePublic: "my_curve_public",
myCurvePrivate: "my_curve_private",
teamEdPublic: "team_ed_public",
teamEdPrivate: "team_ed_private"
};
var team_can_decrypt = function(K) {
return Boolean(K.team_curve_private && K.team_curve_private.length === Nacl.box.secretKeyLength && K.team_ed_public && K.team_ed_public.length === Nacl.sign.publicKeyLength);
};
var team_can_encrypt = function(K) {
return Boolean(K.my_curve_private && K.my_curve_private.length === Nacl.box.secretKeyLength && K.my_curve_public && K.my_curve_public.length === Nacl.box.publicKeyLength && K.team_curve_public && K.team_curve_public.length === Nacl.box.publicKeyLength && K.team_ed_private && K.team_ed_private.length === Nacl.sign.secretKeyLength);
};
var team_validate_own_keys = function(K) {
return Boolean(K.curvePublic && decodeBase64(K.curvePublic).length === Nacl.box.publicKeyLength && K.curvePrivate && decodeBase64(K.curvePrivate).length === Nacl.box.secretKeyLength);
};
var u8_stretch = function(u8) {
var hashed = Nacl.hash(u8);
return [ u8_slice(hashed, 0, 32), u8_slice(hashed, 32) ];
};
var merge = function(o1, o2) {
var o3 = JSON.parse(JSON.stringify(o1));
Object.keys(o2).forEach((function(k) {
o3[k] = o2[k];
}));
return o3;
};
var u8_deriveGuestKeys = function(u8_seed2) {
var stretched = u8_stretch(u8_seed2);
var teamCurve = Nacl.box.keyPair.fromSecretKey(stretched[0]);
var u8_channel = u8_slice(stretched[1], 0, 16);
return {
channel: encodeHex(u8_channel),
teamCurvePublic: encodeBase64(teamCurve.publicKey),
teamCurvePrivate: encodeBase64(teamCurve.secretKey),
viewKeyStr: Crypto.b64RemoveSlashes(encodeBase64(u8_seed2))
};
};
Team.deriveGuestKeys = function(seed2) {
return u8_deriveGuestKeys(decodeBase64(Crypto.b64AddSlashes(seed2)));
};
Team.createSeed = function() {
return Crypto.b64AddSlashes(encodeBase64(Nacl.randomBytes(18)));
};
Team.deriveMemberKeys = function(seed1, myKeys) {
var u8_seed1;
try {
u8_seed1 = decodeBase64(Crypto.b64AddSlashes(seed1));
if (u8_seed1.length < 18) {
throw new Error("INVALID_SEED");
}
} catch (err) {
throw err;
}
if (!team_validate_own_keys(myKeys)) {
throw new Error("INVALID_OWN_KEYS");
}
var stretched = u8_stretch(u8_seed1);
var teamEd = Nacl.sign.keyPair.fromSeed(stretched[0]);
var guestKeys = u8_deriveGuestKeys(stretched[1]);
return merge({
myCurvePublic: myKeys.curvePublic,
myCurvePrivate: myKeys.curvePrivate,
teamEdPrivate: encodeBase64(teamEd.secretKey),
teamEdPublic: encodeBase64(teamEd.publicKey)
}, guestKeys);
};
Team.createEncryptor = function(keys) {
var u8_keys = {};
Object.keys(team_key_map).forEach((function(k) {
if (!keys[k]) {
return;
}
try {
u8_keys[team_key_map[k]] = decodeBase64(keys[k]);
} catch (err) {
console.log(k);
throw new Error("INVALID_KEY_SUPPLIED");
}
}));
var out = {};
if (team_can_encrypt(u8_keys)) {
out.encrypt = function(plain) {
try {
return encryptForTeam(plain, u8_keys);
} catch (e) {
console.error(e);
return null;
}
};
}
if (team_can_decrypt(u8_keys)) {
out.decrypt = function(cipher, skipValidation) {
try {
return decryptForTeam(cipher, u8_keys, skipValidation);
} catch (e) {
console.error(e);
return null;
}
};
}
if (Object.keys(out).length === 0) {
throw new Error("INVALID_TEAM_CONFIGURATION");
}
return out;
};
return Crypto;
};
if (module.exports) {
module.exports = factory(requireNaclFast());
} else {
window.chainpad_crypto = factory(window.nacl);
}
})();
})(crypto);
return crypto.exports;
}
var cryptoExports = requireCrypto();
var networkConfig$1 = {
exports: {}
};
var hasRequiredNetworkConfig;
function requireNetworkConfig() {
if (hasRequiredNetworkConfig) return networkConfig$1.exports;
hasRequiredNetworkConfig = 1;
(function(module) {
(() => {
const factory = (ApiConfig = {}) => {
var Config = {};
Config.setCustomize = data => {
ApiConfig = data.ApiConfig;
};
Config.getWebsocketURL = function(origin) {
var path = ApiConfig.websocketPath || "/cryptpad_websocket";
if (/^ws{1,2}:\/\//.test(path)) {
return path;
}
var l = new URL(origin || self?.location?.href);
if (origin) {
l.href = origin;
}
var protocol = l.protocol.replace(/http/, "ws");
var host = l.host;
var url = protocol + "//" + host + path;
return url;
};
return Config;
};
if (module.exports) {
module.exports = factory();
}
})();
})(networkConfig$1);
return networkConfig$1.exports;
}
var networkConfigExports = requireNetworkConfig();
var networkConfig = getDefaultExportFromCjs(networkConfigExports);
var NetworkConfig = _mergeNamespaces({
__proto__: null,
default: networkConfig
}, [ networkConfigExports ]);
var commonConstants$1 = {
exports: {}
};
var hasRequiredCommonConstants;
function requireCommonConstants() {
if (hasRequiredCommonConstants) return commonConstants$1.exports;
hasRequiredCommonConstants = 1;
(function(module) {
(() => {
const factory = function(AppConfig = {}) {
return {
setCustomize: data => {
AppConfig = data.AppConfig;
},
userHashKey: "User_hash",
userNameKey: "User_name",
blockHashKey: "Block_hash",
fileHashKey: "FS_hash",
sessionJWT: "Session_JWT",
ssoSeed: "SSO_seed",
displayNameKey: "cryptpad.username",
oldStorageKey: "CryptPad_RECENTPADS",
storageKey: "filesData",
tokenKey: "loginToken",
prefersDriveRedirectKey: "prefersDriveRedirect",
isPremiumKey: "isPremiumUser",
displayPadCreationScreen: "displayPadCreationScreen",
deprecatedKey: "deprecated",
MAX_TEAMS_SLOTS: AppConfig.maxTeamsSlots || 5,
MAX_TEAMS_OWNED: AppConfig.maxOwnedTeams || 5,
MAX_PREMIUM_TEAMS_SLOTS: Math.max(AppConfig.maxTeamsSlots || 0, AppConfig.maxPremiumTeamsSlots || 0) || 5,
MAX_PREMIUM_TEAMS_OWNED: Math.max(AppConfig.maxOwnedTeams || 0, AppConfig.maxPremiumTeamsOwned || 0) || 5,
criticalApps: [ "profile", "settings", "debug", "admin", "support", "notifications", "calendar", "moderation", "oldadmin" ],
earlyAccessApps: []
};
};
if (module.exports) {
module.exports = factory(undefined);
}
})();
})(commonConstants$1);
return commonConstants$1.exports;
}
var commonConstantsExports = requireCommonConstants();
var commonConstants = getDefaultExportFromCjs(commonConstantsExports);
var Constants = _mergeNamespaces({
__proto__: null,
default: commonConstants
}, [ commonConstantsExports ]);
var commonHash = {
exports: {}
};
var commonUtil$1 = {
exports: {}
};
var commonUtil = commonUtil$1.exports;
var hasRequiredCommonUtil;
function requireCommonUtil() {
if (hasRequiredCommonUtil) return commonUtil$1.exports;
hasRequiredCommonUtil = 1;
(function(module) {
(function(window) {
var Util = {};
window.atob = window.atob || function(str) {
return Buffer.from(str, "base64").toString("binary");
};
window.btoa = window.btoa || function(str) {
return Buffer.from(str, "binary").toString("base64");
};
Util.slice = function(A, start, end) {
return Array.prototype.slice.call(A, start, end);
};
Util.u8ToBase64 = (u8, cb) => {
const reader = new FileReader;
reader.onload = () => {
let res = reader.result;
let trim = res.slice(res.indexOf(",") + 1);
cb(trim);
};
reader.readAsDataURL(new Blob([ u8 ]));
};
Util.shuffleArray = function(a) {
for (var i = a.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
};
Util.bake = function(f, args) {
if (typeof args === "undefined") {
args = [];
}
if (!Array.isArray(args)) {
args = [ args ];
}
return function() {
return f.apply(null, args);
};
};
Util.both = function(pre, post) {
if (typeof pre !== "function") {
throw new Error("INVALID_USAGE");
}
if (typeof post !== "function") {
post = function(x) {
return x;
};
}
return function() {
pre.apply(null, arguments);
return post.apply(null, arguments);
};
};
Util.clone = function(o) {
if (o === undefined || o === null) {
return o;
}
return JSON.parse(JSON.stringify(o));
};
Util.serializeError = function(err) {
if (!(err instanceof Error)) {
return err;
}
var ser = {};
Object.getOwnPropertyNames(err).forEach((function(key) {
ser[key] = err[key];
}));
return ser;
};
Util.tryParse = function(s) {
try {
return JSON.parse(s);
} catch (e) {
return;
}
};
Util.mkAsync = function(f, ms) {
if (typeof f !== "function") {
throw new Error("EXPECTED_FUNCTION");
}
return function() {
var args = Array.prototype.slice.call(arguments);
setTimeout((function() {
f.apply(null, args);
}), ms);
};
};
Util.mkEvent = function(once) {
var handlers = [];
var fired = false;
let promiseResolve;
const promise = new Promise((resolve => {
promiseResolve = resolve;
}));
return {
reg: function(cb) {
if (once && fired) {
return void setTimeout(cb);
}
handlers.push(cb);
},
unreg: function(cb) {
if (handlers.indexOf(cb) === -1) {
return void console.log("event handler was already unregistered");
}
handlers.splice(handlers.indexOf(cb), 1);
},
fire: function() {
if (once && fired) {
return;
}
var args = Array.prototype.slice.call(arguments);
if (!fired) {
promiseResolve.apply(null, args);
}
fired = true;
handlers.forEach((function(h) {
h.apply(null, args);
}));
},
promise
};
};
Util.mkTimeout = function(_f, ms) {
ms = ms || 0;
var f = Util.once(_f);
var timeout = setTimeout((function() {
f("TIMEOUT");
}), ms);
return Util.both(f, (function() {
clearTimeout(timeout);
}));
};
Util.onClickEnter = function($element, handler, cfg) {
$element.on("click keydown", (function(e) {
var isClick = e.type === "click";
var isEnter = e.type === "keydown" && e.which === 13;
var isSpace = e.type === "keydown" && e.which === 32 && cfg && cfg.space;
if (!isClick && !isEnter && !isSpace) {
return;
}
if (e.type === "keydown") {
e.preventDefault();
}
handler(e);
}));
};
Util.response = function(errorHandler) {
var pending = {};
var timeouts = {};
if (typeof errorHandler !== "function") {
errorHandler = function(label) {
throw new Error(label);
};
}
var clear = function(id) {
clearTimeout(timeouts[id]);
delete timeouts[id];
delete pending[id];
};
var expect = function(id, fn, ms) {
if (typeof id !== "string") {
errorHandler("EXPECTED_STRING");
}
if (typeof fn !== "function") {
errorHandler("EXPECTED_CALLBACK");
}
pending[id] = fn;
if (typeof ms === "number" && ms) {
timeouts[id] = setTimeout((function() {
if (typeof pending[id] === "function") {
pending[id]("TIMEOUT");
}
clear(id);
}), ms);
}
};
var handle = function(id, args) {
var fn = pending[id];
if (typeof fn !== "function") {
return void errorHandler("MISSING_CALLBACK", {
id,
args
});
}
try {
fn.apply(null, Array.isArray(args) ? args : [ args ]);
} catch (err) {
errorHandler("HANDLER_ERROR", {
error: err,
id,
args
});
}
clear(id);
};
return {
clear,
expected: function(id) {
return Boolean(pending[id]);
},
expectation: function(id) {
return pending[id];
},
expect,
handle,
_pending: pending
};
};
Util.inc = function(map, key, val) {
map[key] = (map[key] || 0) + (typeof val === "number" ? val : 1);
};
Util.values = function(obj) {
return Object.keys(obj).map((function(k) {
return obj[k];
}));
};
Util.find = function(map, path) {
var l = path.length;
for (var i = 0; i < l; i++) {
if (typeof map[path[i]] === "undefined") {
return;
}
map = map[path[i]];
}
return map;
};
Util.uid = function() {
return Number(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)).toString(32).replace(/\./g, "");
};
Util.guid = function(map) {
var id = Util.uid();
if (typeof map[id] === "undefined") {
return id;
}
return Util.guid(map);
};
Util.fixHTML = function(str) {
if (!str) {
return "";
}
return str.replace(/[<>&"']/g, (function(x) {
return {
"<": "&lt;",
">": "&gt",
"&": "&amp;",
'"': "&#34;",
"'": "&#39;"
}[x];
}));
};
Util.hexToBase64 = function(hex) {
var hexArray = hex.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" ");
var byteString = String.fromCharCode.apply(null, hexArray);
return window.btoa(byteString).replace(/\//g, "-").replace(/=+$/, "");
};
Util.base64ToHex = function(b64String) {
var hexArray = [];
window.atob(b64String.replace(/-/g, "/")).split("").forEach((function(e) {
var h = e.charCodeAt(0).toString(16);
if (h.length === 1) {
h = "0" + h;
}
hexArray.push(h);
}));
return hexArray.join("");
};
Util.uint8ArrayToHex = function(bytes) {
var hexString = "";
for (var i = 0; i < bytes.length; i++) {
if (bytes[i] < 16) {
hexString += "0";
}
hexString += bytes[i].toString(16);
}
return hexString;
};
Util.hexToUint8Array = function(hexString) {
var bytes = new Uint8Array(Math.ceil(hexString.length / 2));
for (var i = 0; i < bytes.length; i++) {
bytes[i] = parseInt(hexString.substr(i * 2, 2), 16);
}
return bytes;
};
Util.uint8ArrayJoin = function(AA) {
var l = 0;
var i = 0;
for (;i < AA.length; i++) {
l += AA[i].length;
}
var C = new Uint8Array(l);
i = 0;
for (var offset = 0; i < AA.length; i++) {
C.set(AA[i], offset);
offset += AA[i].length;
}
return C;
};
Util.escapeKeyCharacters = function(key) {
return key && key.replace && key.replace(/\//g, "-");
};
Util.unescapeKeyCharacters = function(key) {
return key.replace(/\-/g, "/");
};
Util.deduplicateString = function(array) {
var a = array.slice();
for (var i = 0; i < a.length; i++) {
for (var j = i + 1; j < a.length; j++) {
if (a[i] === a[j]) {
a.splice(j--, 1);
}
}
}
return a;
};
Util.fixFileName = function(filename) {
return filename.replace(/ /g, "-").replace(/[\/\?]/g, "_").replace(/_+/g, "_");
};
var oneKilobyte = 1024;
var oneMegabyte = 1024 * oneKilobyte;
var oneGigabyte = 1024 * oneMegabyte;
Util.bytesToGigabytes = function(bytes) {
return Math.ceil(bytes / oneGigabyte * 100) / 100;
};
Util.bytesToMegabytes = function(bytes) {
return Math.ceil(bytes / oneMegabyte * 100) / 100;
};
Util.bytesToKilobytes = function(bytes) {
return Math.ceil(bytes / oneKilobyte * 100) / 100;
};
Util.magnitudeOfBytes = function(bytes) {
if (bytes >= oneGigabyte) {
return "GB";
} else if (bytes >= oneMegabyte) {
return "MB";
} else {
return "KB";
}
};
var getCacheKey = function(src) {
var _src = src.replace(/(\/)*$/, "");
var idx = _src.lastIndexOf("/");
var cacheKey = _src.slice(idx + 1);
if (!/^[a-f0-9]{48}$/.test(cacheKey)) {
cacheKey = undefined;
}
return cacheKey;
};
Util.getBlock = function(src, opt, cb) {
var CB = Util.once(Util.mkAsync(cb));
var headers = {};
if (typeof opt.bearer === "string" && opt.bearer) {
headers.authorization = `Bearer ${opt.bearer}`;
}
fetch(src, {
method: "GET",
credentials: "include",
headers
}).then((response => {
if (response.ok) {
return void CB(void 0, response);
}
if (response.status === 401 || response.status === 404) {
response.json().then((data => {
CB(response.status, data);
})).catch((() => {
CB(response.status);
}));
return;
}
CB(response.status, response);
})).catch((error => {
CB(error);
}));
};
Util.fetchApi = function(origin, type, ignoreCache, cb) {
const url = new URL(origin);
url.pathname = `api/${type}`;
let href = url.href + (ignoreCache ? "?" + +new Date : "");
if (typeof self !== "undefined" && self.crypto) {
fetch(href).then((res => {
if (!res.ok) {
throw new Error(`Fetch error: ${res.status}`);
}
return res.text();
})).then((body => {
cb(JSON.parse(body.slice(27, -5)));
})).catch((err => {
console.error(err.message);
cb({});
}));
} else if (typeof commonjsRequire !== "undefined") {
const H = url.protocol === "http:" ? require("node:http") : require("node:https");
H.get(url.href, (res => {
let body = "";
res.on("data", (data => {
body += data;
}));
res.on("end", (() => {
try {
cb(JSON.parse(body.slice(27, -5)));
} catch (e) {
console.error(e);
cb({});
}
}));
}));
}
};
Util.fetch = function(src, cb, progress, cache) {
var CB = Util.once(Util.mkAsync(cb));
var cacheKey = getCacheKey(src);
var getBlobCache = function(id, cb) {
if (!cache || typeof cache.getBlobCache !== "function") {
return void cb("EINVAL");
}
cache.getBlobCache(id, cb);
};
var setBlobCache = function(id, u8, cb) {
if (!cache || typeof cache.setBlobCache !== "function") {
return void cb("EINVAL");
}
cache.setBlobCache(id, u8, cb);
};
var xhr;
var fetch = function() {
xhr = new XMLHttpRequest;
xhr.open("GET", src, true);
if (progress) {
xhr.addEventListener("progress", (function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
progress(percentComplete);
}
}), false);
}
xhr.responseType = "arraybuffer";
xhr.onerror = function(err) {
CB(err);
};
xhr.onload = function() {
if (/^4/.test("" + this.status)) {
return CB("XHR_ERROR");
}
var arrayBuffer = xhr.response;
if (arrayBuffer) {
var u8 = new Uint8Array(arrayBuffer);
if (cacheKey) {
return void setBlobCache(cacheKey, u8, (function() {
CB(null, u8);
}));
}
return void CB(void 0, u8);
}
CB("ENOENT");
};
xhr.send(null);
};
if (!cacheKey) {
return void fetch();
}
getBlobCache(cacheKey, (function(err, u8) {
if (err || !u8) {
return void fetch();
}
CB(void 0, u8);
}));
return {
cancel: function() {
if (xhr && xhr.abort) {
xhr.abort();
}
}
};
};
Util.dataURIToBlob = function(dataURI) {
var byteString = atob(dataURI.split(",")[1]);
var mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0];
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
var bb = new Blob([ ab ], {
type: mimeString
});
return bb;
};
Util.throttle = function(f, ms) {
var last = 0;
var to;
var args;
var defer = function(delay) {
to = setTimeout((function() {
to = undefined;
var now = +new Date;
var diff = now - last;
if (diff < ms) {
return void defer(ms - diff);
}
f.apply(null, args);
}), delay);
};
var g = function() {
last = +new Date;
args = Util.slice(arguments);
if (to) {
return;
}
defer(ms);
};
g.clear = function() {
clearTimeout(to);
to = undefined;
};
return g;
};
Util.notAgainForAnother = function(f, t) {
if (typeof f !== "function" || typeof t !== "number") {
throw new Error("invalid inputs");
}
var last = null;
return function() {
var now = +new Date;
if (last && now <= last + t) {
return t - (now - last);
}
last = now;
f.apply(null, Util.slice(arguments));
return null;
};
};
Util.createRandomInteger = function() {
return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
};
Util.noop = function() {};
Util.once = function(f, g) {
return function() {
if (!f) {
return;
}
f.apply(this, Array.prototype.slice.call(arguments));
f = g;
};
};
Util.blobToImage = function(blob, cb) {
var reader = new FileReader;
reader.onloadend = function() {
cb(reader.result);
};
reader.readAsDataURL(blob);
};
Util.blobURLToImage = function(url, cb) {
var xhr = new XMLHttpRequest;
xhr.onload = function() {
var reader = new FileReader;
reader.onloadend = function() {
cb(reader.result);
};
reader.readAsDataURL(xhr.response);
};
xhr.open("GET", url);
xhr.responseType = "blob";
xhr.send();
};
Util.isObject = function(o) {
return typeof o === "object" && Object.prototype.toString.call(o) === "[object Object]";
};
Util.isCircular = function(o) {
try {
JSON.stringify(o);
return false;
} catch (e) {
return true;
}
};
Util.extend = function(a, b) {
if (!Util.isObject(a) || !Util.isObject(b)) {
return void console.log("Extend only works with 2 objects");
}
if (Util.isCircular(b)) {
return void console.log("Extend doesn't accept circular objects");
}
for (var k in b) {
if (Util.isObject(b[k])) {
a[k] = Util.isObject(a[k]) ? a[k] : {};
Util.extend(a[k], b[k]);
continue;
}
if (Array.isArray(b[k])) {
a[k] = b[k].slice();
continue;
}
a[k] = b[k];
}
};
Util.isChecked = function(el) {
if (!el) {
return false;
}
if (typeof el.tagName !== "undefined") {
return Boolean(el.checked);
}
if (typeof el.prop === "function") {
return Boolean(el.prop("checked"));
}
return false;
};
Util.hexToRGB = function(hex) {
var h = hex.replace(/^#/, "");
return [ parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16) ];
};
Util.rgbToHex = function(rgb) {
return `#${rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/).slice(1).map((n => parseInt(n, 10).toString(16).padStart(2, "0"))).join("")}`;
};
Util.isSmallScreen = function() {
return window.innerHeight < 800 || window.innerWidth < 800;
};
Util.stripTags = function(text) {
var div = document.createElement("div");
div.innerHTML = text;
return div.innerText;
};
Util.parseFilename = function(filename) {
if (!filename || !filename.trim()) {
return {};
}
var parsedName = /^(\.?.+?)(\.[^.]+)?$/.exec(filename) || [];
return {
name: parsedName[1],
ext: parsedName[2]
};
};
Util.isPlainTextFile = function(type, name) {
if (type && type.indexOf("text/") === 0) {
return true;
}
var parsedName = Util.parseFilename(name);
if (!type && name && !parsedName.ext) {
return true;
}
if (type === "application/x-javascript") {
return true;
}
if (type === "application/xml") {
return true;
}
return false;
};
Util.isSpreadsheet = function(type, name) {
return type && (type === "application/vnd.oasis.opendocument.spreadsheet" || type === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") || name && (name.endsWith(".xlsx") || name.endsWith(".ods"));
};
Util.isOfficeDoc = function(type, name) {
return type && (type === "application/vnd.oasis.opendocument.text" || type === "application/vnd.openxmlformats-officedocument.wordprocessingml.document") || name && (name.endsWith(".docx") || name.endsWith(".odt"));
};
Util.isPresentation = function(type, name) {
return type && (type === "application/vnd.oasis.opendocument.presentation" || type === "application/vnd.openxmlformats-officedocument.presentationml.presentation") || name && (name.endsWith(".pptx") || name.endsWith(".odp"));
};
Util.isValidURL = function(str) {
var pattern = new RegExp("^(https?:\\/\\/)" + "((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + "((\\d{1,3}\\.){3}\\d{1,3}))" + "(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" + "(\\?[;&a-z\\d%_.~+=-]*)?");
return !!pattern.test(str);
};
var emoji_patt = /([\uD800-\uDBFF][\uDC00-\uDFFF])/;
var isEmoji = function(str) {
return emoji_patt.test(str);
};
var emojiStringToArray = function(str) {
var split = str.split(emoji_patt);
var arr = [];
for (var i = 0; i < split.length; i++) {
var char = split[i];
if (char !== "") {
arr.push(char);
}
}
return arr;
};
Util.getFirstCharacter = function(str) {
if (!str || !str.trim()) {
return "?";
}
var emojis = emojiStringToArray(str);
return isEmoji(emojis[0]) ? emojis[0] : str[0];
};
Util.getRandomColor = function(light) {
var getColor = function() {
if (light) {
return Math.floor(Math.random() * 156) + 70;
}
return Math.floor(Math.random() * 200) + 25;
};
return "#" + getColor().toString(16) + getColor().toString(16) + getColor().toString(16);
};
Util.checkRestrictedApp = function(app, AppConfig, earlyTypes, plan, loggedIn) {
if (Array.isArray(earlyTypes) && earlyTypes.includes(app) && !AppConfig.enableEarlyAccess) {
return -2;
}
var premiumTypes = AppConfig.premiumTypes;
if (!Array.isArray(premiumTypes) || !premiumTypes.includes(app)) {
return 2;
}
if (!loggedIn) {
return -1;
}
return plan ? 1 : 0;
};
var supportsSharedArrayBuffers = function() {
try {
return Object.prototype.toString.call(new window.WebAssembly.Memory({
shared: true,
initial: 0,
maximum: 0
}).buffer) === "[object SharedArrayBuffer]";
} catch (err) {
console.error(err);
}
return false;
};
Util.supportsWasm = function() {
return !(typeof Atomics === "undefined" || !supportsSharedArrayBuffers() || typeof WebAssembly === "undefined");
};
Util.getKeysArray = function(length) {
return [ ...Array(length).keys() ];
};
Util.getVersionFromUrlArgs = urlArgs => {
let arr = /ver=([0-9.]+)(-[0-9]*)?/.exec(urlArgs);
let ver = Array.isArray(arr) && arr[1];
return ver || undefined;
};
Util.Saferphore = {
create: resourceCount => {
var queue = [];
var check;
var mkRa = function() {
var outerCalled = 0;
return function(func) {
if (outerCalled++) {
throw new Error("returnAfter() called multiple times");
}
var called = 0;
return function() {
if (called++) {
throw new Error("returnAfter wrapped callback called multiple times");
}
if (func) {
func.apply(null, arguments);
}
resourceCount++;
check();
};
};
};
check = function() {
if (resourceCount < 0) {
throw new Error("(resourceCount < 0) should never happen");
}
if (resourceCount === 0 || queue.length === 0) {
return;
}
resourceCount--;
queue.shift()(mkRa());
};
return {
take: function(func) {
queue.push(func);
check();
}
};
}
};
if (module.exports) {
module.exports = Util;
} else {
window.CryptPad_Util = Util;
}
})(typeof self !== "undefined" ? self : commonUtil);
})(commonUtil$1);
return commonUtil$1.exports;
}
var commonSigningKeys = {
exports: {}
};
var hasRequiredCommonSigningKeys;
function requireCommonSigningKeys() {
if (hasRequiredCommonSigningKeys) return commonSigningKeys.exports;
hasRequiredCommonSigningKeys = 1;
(function(module) {
(function() {
var factory = function() {
var Keys = {};
var unescape = function(s) {
return s.replace(/-/g, "/");
};
var parseNewUser = function(userString) {
if (!/^\[.*?@.*\]$/.test(userString)) {
return;
}
var temp = userString.slice(1, -1);
var domain, username, pubkey;
temp = temp.replace(/\/([a-zA-Z0-9+-]{43}=)$/, (function(all, k) {
pubkey = unescape(k);
return "";
}));
if (!pubkey) {
return;
}
var index = temp.lastIndexOf("@");
if (index < 1) {
return;
}
domain = temp.slice(index + 1);
username = temp.slice(0, index);
return {
domain,
user: username,
pubkey
};
};
var isValidUser = function(parsed) {
if (!parsed) {
return;
}
if (!(parsed.domain && parsed.user && parsed.pubkey)) {
return;
}
return true;
};
Keys.parseUser = function(user) {
var parsed = parseNewUser(user);
if (isValidUser(parsed)) {
return parsed;
}
var domain, username, pubkey;
user.replace(/^https*:\/\/([^\/]+)\/user\/#\/1\/([^\/]+)\/([a-zA-Z0-9+-]{43}=)$/, (function(a, d, u, k) {
domain = d;
username = u;
pubkey = unescape(k);
return "";
}));
if (!domain) {
throw new Error("Could not parse user id [" + user + "]");
}
return {
domain,
user: username,
pubkey
};
};
Keys.serialize = function(origin, username, pubkey) {
return "[" + username + "@" + origin.replace(/https*:\/\//, "") + "/" + pubkey.replace(/\//g, "-") + "]";
};
Keys.canonicalize = function(input) {
if (typeof input !== "string") {
return;
}
if (input.length === 44) {
return unescape(input);
}
try {
return Keys.parseUser(input).pubkey;
} catch (err) {
return;
}
};
return Keys;
};
if (module.exports) {
module.exports = factory();
}
})();
})(commonSigningKeys);
return commonSigningKeys.exports;
}
var hasRequiredCommonHash;
function requireCommonHash() {
if (hasRequiredCommonHash) return commonHash.exports;
hasRequiredCommonHash = 1;
(function(module) {
(function(window) {
var factory = function(Util, Crypto, Keys, Nacl) {
var Hash = window.CryptPad_Hash = {};
var uint8ArrayToHex = Util.uint8ArrayToHex;
var hexToBase64 = Util.hexToBase64;
var base64ToHex = Util.base64ToHex;
Hash.encodeBase64 = Nacl.util.encodeBase64;
Hash.decodeBase64 = Nacl.util.decodeBase64;
Hash.hashChannelList = function(list) {
return Nacl.util.encodeBase64(Nacl.hash(Nacl.util.decodeUTF8(JSON.stringify(list))));
};
Hash.generateSignPair = function() {
var ed = Nacl.sign.keyPair();
var makeSafe = function(key) {
return Crypto.b64RemoveSlashes(key).replace(/=+$/g, "");
};
return {
validateKey: Hash.encodeBase64(ed.publicKey),
signKey: Hash.encodeBase64(ed.secretKey),
safeValidateKey: makeSafe(Hash.encodeBase64(ed.publicKey)),
safeSignKey: makeSafe(Hash.encodeBase64(ed.secretKey))
};
};
Hash.getSignPublicFromPrivate = function(edPrivateSafeStr) {
var edPrivateStr = Crypto.b64AddSlashes(edPrivateSafeStr);
var privateKey = Nacl.util.decodeBase64(edPrivateStr);
var keyPair = Nacl.sign.keyPair.fromSecretKey(privateKey);
return Nacl.util.encodeBase64(keyPair.publicKey);
};
Hash.getCurvePublicFromPrivate = function(curvePrivateSafeStr) {
var curvePrivateStr = Crypto.b64AddSlashes(curvePrivateSafeStr);
var privateKey = Nacl.util.decodeBase64(curvePrivateStr);
var keyPair = Nacl.box.keyPair.fromSecretKey(privateKey);
return Nacl.util.encodeBase64(keyPair.publicKey);
};
var getEditHashFromKeys = Hash.getEditHashFromKeys = function(secret) {
var version = secret.version;
var data = secret.keys;
if (version === 0) {
return secret.channel + secret.key;
}
if (version === 1) {
if (!data.editKeyStr) {
return;
}
return "/1/edit/" + hexToBase64(secret.channel) + "/" + Crypto.b64RemoveSlashes(data.editKeyStr) + "/";
}
if (version === 2) {
if (!data.editKeyStr) {
return;
}
var pass = secret.password ? "p/" : "";
return "/2/" + secret.type + "/edit/" + Crypto.b64RemoveSlashes(data.editKeyStr) + "/" + pass;
}
};
var getViewHashFromKeys = Hash.getViewHashFromKeys = function(secret) {
var version = secret.version;
var data = secret.keys;
if (version === 0) {
return;
}
if (version === 1) {
if (!data.viewKeyStr) {
return;
}
return "/1/view/" + hexToBase64(secret.channel) + "/" + Crypto.b64RemoveSlashes(data.viewKeyStr) + "/";
}
if (version === 2) {
if (!data.viewKeyStr) {
return;
}
var pass = secret.password ? "p/" : "";
return "/2/" + secret.type + "/view/" + Crypto.b64RemoveSlashes(data.viewKeyStr) + "/" + pass;
}
};
Hash.getHiddenHashFromKeys = function(type, secret, opts) {
opts = opts || {};
var canEdit = secret.keys && secret.keys.editKeyStr || secret.key;
var mode = !opts.view && canEdit ? "edit/" : "view/";
var pass = secret.password ? "p/" : "";
if (secret.keys && secret.keys.fileKeyStr) {
mode = "";
}
var hash = "/3/" + type + "/" + mode + secret.channel + "/" + pass;
var hashData = Hash.parseTypeHash(type, hash);
if (hashData && hashData.getHash) {
return hashData.getHash(opts || {});
}
return hash;
};
var getFileHashFromKeys = Hash.getFileHashFromKeys = function(secret) {
var version = secret.version;
var data = secret.keys;
if (version === 0) {
return;
}
if (version === 1) {
return "/1/" + hexToBase64(secret.channel) + "/" + Crypto.b64RemoveSlashes(data.fileKeyStr) + "/";
}
if (version === 2) {
if (!data.fileKeyStr) {
return;
}
var pass = secret.password ? "p/" : "";
return "/2/" + secret.type + "/" + Crypto.b64RemoveSlashes(data.fileKeyStr) + "/" + pass;
}
};
Hash.getPublicSigningKeyString = Keys.serialize;
var fixDuplicateSlashes = function(s) {
return s.replace(/\/+/g, "/");
};
Hash.ephemeralChannelLength = 34;
Hash.createChannelId = function(ephemeral) {
var id = uint8ArrayToHex(Crypto.Nacl.randomBytes(ephemeral ? 17 : 16));
if ([ 32, 34 ].indexOf(id.length) === -1 || /[^a-f0-9]/.test(id)) {
throw new Error("channel ids must consist of 32 hex characters");
}
return id;
};
Hash.getChannelIdFromKey = function(publicKey) {
if (!publicKey) {
return;
}
return uint8ArrayToHex(Hash.decodeBase64(publicKey).subarray(0, 16));
};
Hash.getBoxPublicFromSecret = function(priv) {
if (!priv) {
return;
}
var u8_priv = Hash.decodeBase64(priv);
var pair = Nacl.box.keyPair.fromSecretKey(u8_priv);
return Hash.encodeBase64(pair.publicKey);
};
Hash.checkBoxKeyPair = function(priv, pub) {
if (!pub || !priv) {
return false;
}
var u8_priv = Hash.decodeBase64(priv);
var pair = Nacl.box.keyPair.fromSecretKey(u8_priv);
return pub === Hash.encodeBase64(pair.publicKey);
};
Hash.createRandomHash = function(type, password) {
var cryptor;
if (type === "file") {
cryptor = Crypto.createFileCryptor2(void 0, password);
return getFileHashFromKeys({
password: Boolean(password),
version: 2,
type,
keys: cryptor
});
}
cryptor = Crypto.createEditCryptor2(void 0, void 0, password);
return getEditHashFromKeys({
password: Boolean(password),
version: 2,
type,
keys: cryptor
});
};
var getLoginOpts = function(hashArr) {
var k;
hashArr.some((function(data) {
if (/^login=/.test(data)) {
k = data.slice(6);
return true;
}
}));
return k || "";
};
var getNewPadOpts = function(hashArr) {
var k;
hashArr.some((function(data) {
if (/^newpad=/.test(data)) {
k = data.slice(7);
return true;
}
}));
return k || "";
};
var getVersionHash = function(hashArr) {
var k;
hashArr.some((function(data) {
if (/^hash=/.test(data)) {
k = data.slice(5);
return true;
}
}));
return k ? Crypto.b64AddSlashes(k) : "";
};
var getAuditorKey = function(hashArr) {
var k;
hashArr.some((function(data) {
if (/^auditor=/.test(data)) {
k = data.slice(8);
return true;
}
}));
return k ? Crypto.b64AddSlashes(k) : "";
};
var getOwnerKey = function(hashArr) {
var k;
hashArr.some((function(data) {
if (data.length === 86) {
k = data;
return true;
}
}));
return k;
};
var parseTypeHash = Hash.parseTypeHash = function(type, hash) {
if (!hash) {
return;
}
var options = [];
var parsed = {};
var hashArr = fixDuplicateSlashes(hash).split("/");
var addOptions = function() {
parsed.password = options.indexOf("p") !== -1;
parsed.present = options.indexOf("present") !== -1;
parsed.embed = options.indexOf("embed") !== -1;
parsed.versionHash = getVersionHash(options);
parsed.auditorKey = getAuditorKey(options);
parsed.newPadOpts = getNewPadOpts(options);
parsed.loginOpts = getLoginOpts(options);
parsed.ownerKey = getOwnerKey(options);
};
if (hashArr[1] && hashArr[1] === "4") {
parsed.getHash = function(opts) {
if (!opts || !Object.keys(opts).length) {
return "";
}
var hash = "/4/" + type + "/";
if (opts.newPadOpts) {
hash += "newpad=" + opts.newPadOpts + "/";
}
if (opts.loginOpts) {
hash += "login=" + opts.loginOpts + "/";
}
return hash;
};
parsed.getOptions = function() {
var options = {};
if (parsed.newPadOpts) {
options.newPadOpts = parsed.newPadOpts;
}
if (parsed.loginOpts) {
options.loginOpts = parsed.loginOpts;
}
return options;
};
parsed.version = 4;
parsed.app = hashArr[2];
options = hashArr.slice(3);
addOptions();
return parsed;
}
if ([ "media", "file", "user", "invite" ].indexOf(type) === -1) {
parsed.type = "pad";
parsed.getHash = function() {
return hash;
};
parsed.getOptions = function() {
return {
embed: parsed.embed,
present: parsed.present,
ownerKey: parsed.ownerKey,
versionHash: parsed.versionHash,
auditorKey: parsed.auditorKey,
newPadOpts: parsed.newPadOpts,
loginOpts: parsed.loginOpts,
password: parsed.password
};
};
if (hash.slice(0, 1) !== "/" && hash.length >= 56) {
parsed.channel = hash.slice(0, 32);
parsed.key = hash.slice(32, 56);
parsed.version = 0;
return parsed;
}
parsed.getHash = function(opts) {
var hash = hashArr.slice(0, 5).join("/") + "/";
var owner = typeof opts.ownerKey !== "undefined" ? opts.ownerKey : parsed.ownerKey;
if (owner) {
hash += owner + "/";
}
if (parsed.password || opts.password) {
hash += "p/";
}
if (opts.embed) {
hash += "embed/";
}
if (opts.present) {
hash += "present/";
}
var versionHash = typeof opts.versionHash !== "undefined" ? opts.versionHash : parsed.versionHash;
if (versionHash) {
hash += "hash=" + Crypto.b64RemoveSlashes(versionHash) + "/";
}
var auditorKey = typeof opts.auditorKey !== "undefined" ? opts.auditorKey : parsed.auditorKey;
if (auditorKey) {
hash += "auditor=" + Crypto.b64RemoveSlashes(auditorKey) + "/";
}
if (opts.newPadOpts) {
hash += "newpad=" + opts.newPadOpts + "/";
}
if (opts.loginOpts) {
hash += "login=" + opts.loginOpts + "/";
}
return hash;
};
if (hashArr[1] && hashArr[1] === "1") {
parsed.version = 1;
parsed.mode = hashArr[2];
parsed.channel = hashArr[3];
parsed.key = Crypto.b64AddSlashes(hashArr[4]);
options = hashArr.slice(5);
addOptions();
return parsed;
}
if (hashArr[1] && hashArr[1] === "2") {
parsed.version = 2;
parsed.app = hashArr[2];
parsed.mode = hashArr[3];
parsed.key = hashArr[4];
options = hashArr.slice(5);
addOptions();
return parsed;
}
if (hashArr[1] && hashArr[1] === "3") {
parsed.version = 3;
parsed.app = hashArr[2];
parsed.mode = hashArr[3];
parsed.channel = hashArr[4];
options = hashArr.slice(5);
addOptions();
return parsed;
}
return parsed;
}
parsed.getHash = function() {
return hashArr.join("/");
};
if ([ "media", "file" ].indexOf(type) !== -1) {
parsed.type = "file";
parsed.getOptions = function() {
return {
embed: parsed.embed,
present: parsed.present,
ownerKey: parsed.ownerKey,
newPadOpts: parsed.newPadOpts,
loginOpts: parsed.loginOpts,
password: parsed.password
};
};
parsed.getHash = function(opts) {
var hash = hashArr.slice(0, 4).join("/") + "/";
var owner = typeof opts.ownerKey !== "undefined" ? opts.ownerKey : parsed.ownerKey;
if (owner) {
hash += owner + "/";
}
if (parsed.password || opts.password) {
hash += "p/";
}
if (opts.embed) {
hash += "embed/";
}
if (opts.present) {
hash += "present/";
}
if (opts.newPadOpts) {
hash += "newpad=" + opts.newPadOpts + "/";
}
if (opts.loginOpts) {
hash += "login=" + opts.loginOpts + "/";
}
return hash;
};
if (hashArr[1] && hashArr[1] === "1") {
parsed.version = 1;
parsed.channel = hashArr[2].replace(/-/g, "/");
parsed.key = hashArr[3].replace(/-/g, "/");
options = hashArr.slice(4);
addOptions();
return parsed;
}
if (hashArr[1] && hashArr[1] === "2") {
parsed.version = 2;
parsed.app = hashArr[2];
parsed.key = hashArr[3];
options = hashArr.slice(4);
addOptions();
return parsed;
}
if (hashArr[1] && hashArr[1] === "3") {
parsed.version = 3;
parsed.app = hashArr[2];
parsed.channel = hashArr[3];
options = hashArr.slice(4);
addOptions();
return parsed;
}
return parsed;
}
if ([ "user" ].indexOf(type) !== -1) {
parsed.type = "user";
if (hashArr[1] && hashArr[1] === "1") {
parsed.version = 1;
parsed.user = hashArr[2];
parsed.pubkey = hashArr[3].replace(/-/g, "/");
return parsed;
}
return parsed;
}
if ([ "invite" ].indexOf(type) !== -1) {
parsed.type = "invite";
if (hashArr[1] && hashArr[1] === "2") {
parsed.version = 2;
parsed.app = hashArr[2];
parsed.mode = hashArr[3];
parsed.key = hashArr[4];
options = hashArr.slice(5);
parsed.password = options.indexOf("p") !== -1;
return parsed;
}
return parsed;
}
return;
};
var parsePadUrl = Hash.parsePadUrl = function(href) {
var patt = /^https*:\/\/([^\/]*)\/(.*?)\//i;
var ret = {};
if (!href) {
return ret;
}
if (href.slice(-1) !== "/" && href.slice(-1) !== "#") {
href += "/";
}
href = href.replace(/\/\?[^#]+#/, "/#");
var idx;
var getHash = function(opts) {
if (!opts || !Object.keys(opts).length) {
return "";
}
var hash = "/4/" + ret.type + "/";
if (opts.newPadOpts) {
hash += "newpad=" + opts.newPadOpts + "/";
}
if (opts.loginOpts) {
hash += "login=" + opts.loginOpts + "/";
}
return hash;
};
ret.getUrl = function(options) {
options = options || {};
var url = "/";
if (!ret.type) {
return url;
}
url += ret.type + "/";
if (!ret.hashData && options && Object.keys(options).length) {
return url + "#" + getHash(options);
}
if (!ret.hashData) {
return url;
}
var hash = ret.hashData.getHash(options);
url += "#" + hash;
return url;
};
ret.getOptions = function() {
if (!ret.hashData || !ret.hashData.getOptions) {
return {};
}
return ret.hashData.getOptions();
};
if (!/^https*:\/\//.test(href)) {
if (!/^\/($|[^\/])/.test(href)) {
return ret;
}
idx = href.indexOf("/#");
ret.type = href.slice(1, idx);
if (idx === -1) {
return ret;
}
ret.hash = href.slice(idx + 2);
ret.hashData = parseTypeHash(ret.type, ret.hash);
return ret;
}
href.replace(patt, (function(a, domain, type) {
ret.domain = domain;
ret.type = type;
return "";
}));
idx = href.indexOf("/#");
if (idx === -1) {
return ret;
}
ret.hash = href.slice(idx + 2);
ret.hashData = parseTypeHash(ret.type, ret.hash);
return ret;
};
Hash.hashToHref = function(hash, type) {
return "/" + type + "/#" + hash;
};
Hash.hrefToHash = function(href) {
var parsed = Hash.parsePadUrl(href);
return parsed.hash;
};
Hash.getRelativeHref = function(href) {
if (!href) {
return;
}
if (href.indexOf("#") === -1) {
return;
}
var parsed = parsePadUrl(href);
return "/" + parsed.type + "/#" + parsed.hash;
};
Hash.getSecrets = function(type, secretHash, password) {
var secret = {};
var generate = function() {
secret.keys = Crypto.createEditCryptor2(void 0, void 0, password);
secret.channel = base64ToHex(secret.keys.chanId);
secret.version = 2;
secret.type = type;
};
if (!secretHash) {
generate();
return secret;
} else {
var parsed;
var hash;
if (secretHash) {
if (!type) {
throw new Error("getSecrets with a hash requires a type parameter");
}
parsed = parseTypeHash(type, secretHash);
hash = secretHash;
}
if (hash.length === 0) {
generate();
return secret;
}
if (parsed.version === 0) {
secret.channel = parsed.channel;
secret.key = parsed.key;
secret.version = 0;
} else if (parsed.version === 1) {
secret.version = 1;
if (parsed.type === "pad") {
secret.channel = base64ToHex(parsed.channel);
if (parsed.mode === "edit") {
secret.keys = Crypto.createEditCryptor(parsed.key);
secret.key = secret.keys.editKeyStr;
if (secret.channel.length !== 32 || secret.key.length !== 24) {
throw new Error("The channel key and/or the encryption key is invalid");
}
} else if (parsed.mode === "view") {
secret.keys = Crypto.createViewCryptor(parsed.key);
if (secret.channel.length !== 32) {
throw new Error("The channel key is invalid");
}
}
} else if (parsed.type === "file") {
secret.channel = base64ToHex(parsed.channel);
secret.keys = {
fileKeyStr: parsed.key,
cryptKey: Nacl.util.decodeBase64(parsed.key)
};
} else if (parsed.type === "user") {
throw new Error("User hashes can't be opened (yet)");
}
} else if (parsed.version === 2) {
secret.version = 2;
secret.type = type;
secret.password = password;
if (parsed.type === "pad") {
if (parsed.mode === "edit") {
secret.keys = Crypto.createEditCryptor2(parsed.key, void 0, password);
secret.channel = base64ToHex(secret.keys.chanId);
secret.key = secret.keys.editKeyStr;
if (secret.channel.length !== 32 || secret.key.length !== 24) {
throw new Error("The channel key and/or the encryption key is invalid");
}
} else if (parsed.mode === "view") {
secret.keys = Crypto.createViewCryptor2(parsed.key, password);
secret.channel = base64ToHex(secret.keys.chanId);
if (secret.channel.length !== 32) {
throw new Error("The channel key is invalid");
}
}
} else if (parsed.type === "file") {
secret.keys = Crypto.createFileCryptor2(parsed.key, password);
secret.channel = base64ToHex(secret.keys.chanId);
secret.key = secret.keys.fileKeyStr;
if (secret.channel.length !== 48 || secret.key.length !== 24) {
throw new Error("The channel key and/or the encryption key is invalid");
}
} else if (parsed.type === "user") {
throw new Error("User hashes can't be opened (yet)");
}
}
}
return secret;
};
Hash.getHashes = function(secret) {
var hashes = {};
secret = JSON.parse(JSON.stringify(secret));
if (!secret.keys && !secret.key) {
return hashes;
} else if (!secret.keys) {
secret.keys = {};
}
if (secret.keys.editKeyStr || secret.version === 0 && secret.key) {
hashes.editHash = getEditHashFromKeys(secret);
}
if (secret.keys.viewKeyStr) {
hashes.viewHash = getViewHashFromKeys(secret);
}
if (secret.keys.fileKeyStr) {
hashes.fileHash = getFileHashFromKeys(secret);
}
return hashes;
};
Hash.getFormData = function(secret, hash, password) {
secret = secret || Hash.getSecrets("form", hash, password);
var keys = secret && secret.keys;
var secondary = keys && keys.secondaryKey;
if (!secondary) {
return;
}
var curvePair = Nacl.box.keyPair.fromSecretKey(Nacl.util.decodeUTF8(secondary).slice(0, 32));
var ret = {};
ret.form_public = Nacl.util.encodeBase64(curvePair.publicKey);
var privateKey = ret.form_private = Nacl.util.encodeBase64(curvePair.secretKey);
var auditorHash = Hash.getViewHashFromKeys({
version: 1,
channel: secret.channel,
keys: {
viewKeyStr: Nacl.util.encodeBase64(keys.cryptKey)
}
});
var _parsed = Hash.parseTypeHash("pad", auditorHash);
ret.form_auditorHash = _parsed.getHash({
auditorKey: privateKey
});
return ret;
};
Hash.hrefToHexChannelId = function(href, password) {
var parsed = Hash.parsePadUrl(href);
if (!parsed || !parsed.hash) {
return;
}
var secret = Hash.getSecrets(parsed.type, parsed.hash, password);
return secret.channel;
};
Hash.getBlobPathFromHex = function(id) {
return "/blob/" + id.slice(0, 2) + "/" + id;
};
Hash.serializeHash = function(hash) {
if (hash && hash.slice(-1) !== "/") {
hash += "/";
}
return hash;
};
Hash.createInviteUrl = function(curvePublic, channel) {
channel = channel || Hash.createChannelId();
return window.location.origin + "/invite/#/1/" + channel + "/" + curvePublic.replace(/\//g, "-") + "/";
};
Hash.isValidChannel = function(channelId) {
return /^[a-zA-Z0-9]{32,48}$/.test(channelId);
};
Hash.isValidHref = function(href) {
if (!href) {
return;
}
var parsed = Hash.parsePadUrl(href);
if (!parsed) {
return;
}
if (!parsed.type) {
return;
}
if (parsed.hash) {
if (!parsed.hashData) {
return;
}
if (typeof parsed.hashData.version === "undefined") {
return;
}
if (parsed.hashData.type === "pad" || parsed.hashData.type === "file") {
if (!parsed.hashData.key && !parsed.hashData.channel) {
return;
}
if (parsed.hashData.key && !/^[a-zA-Z0-9+-/=]+$/.test(parsed.hashData.key)) {
return;
}
}
}
return parsed;
};
Hash.decodeDataOptions = function(opts) {
var b64 = decodeURIComponent(opts);
var str = Nacl.util.encodeUTF8(Nacl.util.decodeBase64(b64));
return Util.tryParse(str) || {};
};
Hash.encodeDataOptions = function(opts) {
var str = JSON.stringify(opts);
var b64 = Nacl.util.encodeBase64(Nacl.util.decodeUTF8(str));
return encodeURIComponent(b64);
};
Hash.getNewPadURL = function(href, opts) {
var parsed = Hash.parsePadUrl(href);
var options = parsed.getOptions();
options.newPadOpts = Hash.encodeDataOptions(opts);
return parsed.getUrl(options);
};
Hash.getLoginURL = function(href, opts) {
var parsed = Hash.parsePadUrl(href);
var options = parsed.getOptions();
options.loginOpts = Hash.encodeDataOptions(opts);
return parsed.getUrl(options);
};
return Hash;
};
if (module.exports) {
module.exports = factory(requireCommonUtil(), requireCrypto(), requireCommonSigningKeys(), requireNaclFast());
}
})(typeof window !== "undefined" ? window : {});
})(commonHash);
return commonHash.exports;
}
var commonHashExports = requireCommonHash();
var commonUtilExports = requireCommonUtil();
var cacheStore$1 = {
exports: {}
};
var localforage = {
exports: {}
};
/*!
localForage -- Offline Storage, Improved
Version 1.10.0
https://localforage.github.io/localForage
(c) 2013-2017 Mozilla, Apache License 2.0
*/ var hasRequiredLocalforage;
function requireLocalforage() {
if (hasRequiredLocalforage) return localforage.exports;
hasRequiredLocalforage = 1;
(function(module, exports) {
(function(f) {
{
module.exports = f();
}
})((function() {
return function e(t, n, r) {
function s(o, u) {
if (!n[o]) {
if (!t[o]) {
var a = typeof commonjsRequire == "function" && commonjsRequire;
if (!u && a) return a(o, !0);
if (i) return i(o, !0);
var f = new Error("Cannot find module '" + o + "'");
throw f.code = "MODULE_NOT_FOUND", f;
}
var l = n[o] = {
exports: {}
};
t[o][0].call(l.exports, (function(e) {
var n = t[o][1][e];
return s(n ? n : e);
}), l, l.exports, e, t, n, r);
}
return n[o].exports;
}
var i = typeof commonjsRequire == "function" && commonjsRequire;
for (var o = 0; o < r.length; o++) s(r[o]);
return s;
}({
1: [ function(_dereq_, module, exports) {
(function(global) {
var Mutation = global.MutationObserver || global.WebKitMutationObserver;
var scheduleDrain;
{
if (Mutation) {
var called = 0;
var observer = new Mutation(nextTick);
var element = global.document.createTextNode("");
observer.observe(element, {
characterData: true
});
scheduleDrain = function() {
element.data = called = ++called % 2;
};
} else if (!global.setImmediate && typeof global.MessageChannel !== "undefined") {
var channel = new global.MessageChannel;
channel.port1.onmessage = nextTick;
scheduleDrain = function() {
channel.port2.postMessage(0);
};
} else if ("document" in global && "onreadystatechange" in global.document.createElement("script")) {
scheduleDrain = function() {
var scriptEl = global.document.createElement("script");
scriptEl.onreadystatechange = function() {
nextTick();
scriptEl.onreadystatechange = null;
scriptEl.parentNode.removeChild(scriptEl);
scriptEl = null;
};
global.document.documentElement.appendChild(scriptEl);
};
} else {
scheduleDrain = function() {
setTimeout(nextTick, 0);
};
}
}
var draining;
var queue = [];
function nextTick() {
draining = true;
var i, oldQueue;
var len = queue.length;
while (len) {
oldQueue = queue;
queue = [];
i = -1;
while (++i < len) {
oldQueue[i]();
}
len = queue.length;
}
draining = false;
}
module.exports = immediate;
function immediate(task) {
if (queue.push(task) === 1 && !draining) {
scheduleDrain();
}
}
}).call(this, typeof commonjsGlobal !== "undefined" ? commonjsGlobal : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
}, {} ],
2: [ function(_dereq_, module, exports) {
var immediate = _dereq_(1);
function INTERNAL() {}
var handlers = {};
var REJECTED = [ "REJECTED" ];
var FULFILLED = [ "FULFILLED" ];
var PENDING = [ "PENDING" ];
module.exports = Promise;
function Promise(resolver) {
if (typeof resolver !== "function") {
throw new TypeError("resolver must be a function");
}
this.state = PENDING;
this.queue = [];
this.outcome = void 0;
if (resolver !== INTERNAL) {
safelyResolveThenable(this, resolver);
}
}
Promise.prototype["catch"] = function(onRejected) {
return this.then(null, onRejected);
};
Promise.prototype.then = function(onFulfilled, onRejected) {
if (typeof onFulfilled !== "function" && this.state === FULFILLED || typeof onRejected !== "function" && this.state === REJECTED) {
return this;
}
var promise = new this.constructor(INTERNAL);
if (this.state !== PENDING) {
var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
unwrap(promise, resolver, this.outcome);
} else {
this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
}
return promise;
};
function QueueItem(promise, onFulfilled, onRejected) {
this.promise = promise;
if (typeof onFulfilled === "function") {
this.onFulfilled = onFulfilled;
this.callFulfilled = this.otherCallFulfilled;
}
if (typeof onRejected === "function") {
this.onRejected = onRejected;
this.callRejected = this.otherCallRejected;
}
}
QueueItem.prototype.callFulfilled = function(value) {
handlers.resolve(this.promise, value);
};
QueueItem.prototype.otherCallFulfilled = function(value) {
unwrap(this.promise, this.onFulfilled, value);
};
QueueItem.prototype.callRejected = function(value) {
handlers.reject(this.promise, value);
};
QueueItem.prototype.otherCallRejected = function(value) {
unwrap(this.promise, this.onRejected, value);
};
function unwrap(promise, func, value) {
immediate((function() {
var returnValue;
try {
returnValue = func(value);
} catch (e) {
return handlers.reject(promise, e);
}
if (returnValue === promise) {
handlers.reject(promise, new TypeError("Cannot resolve promise with itself"));
} else {
handlers.resolve(promise, returnValue);
}
}));
}
handlers.resolve = function(self, value) {
var result = tryCatch(getThen, value);
if (result.status === "error") {
return handlers.reject(self, result.value);
}
var thenable = result.value;
if (thenable) {
safelyResolveThenable(self, thenable);
} else {
self.state = FULFILLED;
self.outcome = value;
var i = -1;
var len = self.queue.length;
while (++i < len) {
self.queue[i].callFulfilled(value);
}
}
return self;
};
handlers.reject = function(self, error) {
self.state = REJECTED;
self.outcome = error;
var i = -1;
var len = self.queue.length;
while (++i < len) {
self.queue[i].callRejected(error);
}
return self;
};
function getThen(obj) {
var then = obj && obj.then;
if (obj && (typeof obj === "object" || typeof obj === "function") && typeof then === "function") {
return function appyThen() {
then.apply(obj, arguments);
};
}
}
function safelyResolveThenable(self, thenable) {
var called = false;
function onError(value) {
if (called) {
return;
}
called = true;
handlers.reject(self, value);
}
function onSuccess(value) {
if (called) {
return;
}
called = true;
handlers.resolve(self, value);
}
function tryToUnwrap() {
thenable(onSuccess, onError);
}
var result = tryCatch(tryToUnwrap);
if (result.status === "error") {
onError(result.value);
}
}
function tryCatch(func, value) {
var out = {};
try {
out.value = func(value);
out.status = "success";
} catch (e) {
out.status = "error";
out.value = e;
}
return out;
}
Promise.resolve = resolve;
function resolve(value) {
if (value instanceof this) {
return value;
}
return handlers.resolve(new this(INTERNAL), value);
}
Promise.reject = reject;
function reject(reason) {
var promise = new this(INTERNAL);
return handlers.reject(promise, reason);
}
Promise.all = all;
function all(iterable) {
var self = this;
if (Object.prototype.toString.call(iterable) !== "[object Array]") {
return this.reject(new TypeError("must be an array"));
}
var len = iterable.length;
var called = false;
if (!len) {
return this.resolve([]);
}
var values = new Array(len);
var resolved = 0;
var i = -1;
var promise = new this(INTERNAL);
while (++i < len) {
allResolver(iterable[i], i);
}
return promise;
function allResolver(value, i) {
self.resolve(value).then(resolveFromAll, (function(error) {
if (!called) {
called = true;
handlers.reject(promise, error);
}
}));
function resolveFromAll(outValue) {
values[i] = outValue;
if (++resolved === len && !called) {
called = true;
handlers.resolve(promise, values);
}
}
}
}
Promise.race = race;
function race(iterable) {
var self = this;
if (Object.prototype.toString.call(iterable) !== "[object Array]") {
return this.reject(new TypeError("must be an array"));
}
var len = iterable.length;
var called = false;
if (!len) {
return this.resolve([]);
}
var i = -1;
var promise = new this(INTERNAL);
while (++i < len) {
resolver(iterable[i]);
}
return promise;
function resolver(value) {
self.resolve(value).then((function(response) {
if (!called) {
called = true;
handlers.resolve(promise, response);
}
}), (function(error) {
if (!called) {
called = true;
handlers.reject(promise, error);
}
}));
}
}
}, {
1: 1
} ],
3: [ function(_dereq_, module, exports) {
(function(global) {
if (typeof global.Promise !== "function") {
global.Promise = _dereq_(2);
}
}).call(this, typeof commonjsGlobal !== "undefined" ? commonjsGlobal : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
}, {
2: 2
} ],
4: [ function(_dereq_, module, exports) {
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function(obj) {
return typeof obj;
} : function(obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function getIDB() {
try {
if (typeof indexedDB !== "undefined") {
return indexedDB;
}
if (typeof webkitIndexedDB !== "undefined") {
return webkitIndexedDB;
}
if (typeof mozIndexedDB !== "undefined") {
return mozIndexedDB;
}
if (typeof OIndexedDB !== "undefined") {
return OIndexedDB;
}
if (typeof msIndexedDB !== "undefined") {
return msIndexedDB;
}
} catch (e) {
return;
}
}
var idb = getIDB();
function isIndexedDBValid() {
try {
if (!idb || !idb.open) {
return false;
}
var isSafari = typeof openDatabase !== "undefined" && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform);
var hasFetch = typeof fetch === "function" && fetch.toString().indexOf("[native code") !== -1;
return (!isSafari || hasFetch) && typeof indexedDB !== "undefined" && typeof IDBKeyRange !== "undefined";
} catch (e) {
return false;
}
}
function createBlob(parts, properties) {
parts = parts || [];
properties = properties || {};
try {
return new Blob(parts, properties);
} catch (e) {
if (e.name !== "TypeError") {
throw e;
}
var Builder = typeof BlobBuilder !== "undefined" ? BlobBuilder : typeof MSBlobBuilder !== "undefined" ? MSBlobBuilder : typeof MozBlobBuilder !== "undefined" ? MozBlobBuilder : WebKitBlobBuilder;
var builder = new Builder;
for (var i = 0; i < parts.length; i += 1) {
builder.append(parts[i]);
}
return builder.getBlob(properties.type);
}
}
if (typeof Promise === "undefined") {
_dereq_(3);
}
var Promise$1 = Promise;
function executeCallback(promise, callback) {
if (callback) {
promise.then((function(result) {
callback(null, result);
}), (function(error) {
callback(error);
}));
}
}
function executeTwoCallbacks(promise, callback, errorCallback) {
if (typeof callback === "function") {
promise.then(callback);
}
if (typeof errorCallback === "function") {
promise["catch"](errorCallback);
}
}
function normalizeKey(key) {
if (typeof key !== "string") {
console.warn(key + " used as a key, but it is not a string.");
key = String(key);
}
return key;
}
function getCallback() {
if (arguments.length && typeof arguments[arguments.length - 1] === "function") {
return arguments[arguments.length - 1];
}
}
var DETECT_BLOB_SUPPORT_STORE = "local-forage-detect-blob-support";
var supportsBlobs = void 0;
var dbContexts = {};
var toString = Object.prototype.toString;
var READ_ONLY = "readonly";
var READ_WRITE = "readwrite";
function _binStringToArrayBuffer(bin) {
var length = bin.length;
var buf = new ArrayBuffer(length);
var arr = new Uint8Array(buf);
for (var i = 0; i < length; i++) {
arr[i] = bin.charCodeAt(i);
}
return buf;
}
function _checkBlobSupportWithoutCaching(idb) {
return new Promise$1((function(resolve) {
var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, READ_WRITE);
var blob = createBlob([ "" ]);
txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, "key");
txn.onabort = function(e) {
e.preventDefault();
e.stopPropagation();
resolve(false);
};
txn.oncomplete = function() {
var matchedChrome = navigator.userAgent.match(/Chrome\/(\d+)/);
var matchedEdge = navigator.userAgent.match(/Edge\//);
resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43);
};
}))["catch"]((function() {
return false;
}));
}
function _checkBlobSupport(idb) {
if (typeof supportsBlobs === "boolean") {
return Promise$1.resolve(supportsBlobs);
}
return _checkBlobSupportWithoutCaching(idb).then((function(value) {
supportsBlobs = value;
return supportsBlobs;
}));
}
function _deferReadiness(dbInfo) {
var dbContext = dbContexts[dbInfo.name];
var deferredOperation = {};
deferredOperation.promise = new Promise$1((function(resolve, reject) {
deferredOperation.resolve = resolve;
deferredOperation.reject = reject;
}));
dbContext.deferredOperations.push(deferredOperation);
if (!dbContext.dbReady) {
dbContext.dbReady = deferredOperation.promise;
} else {
dbContext.dbReady = dbContext.dbReady.then((function() {
return deferredOperation.promise;
}));
}
}
function _advanceReadiness(dbInfo) {
var dbContext = dbContexts[dbInfo.name];
var deferredOperation = dbContext.deferredOperations.pop();
if (deferredOperation) {
deferredOperation.resolve();
return deferredOperation.promise;
}
}
function _rejectReadiness(dbInfo, err) {
var dbContext = dbContexts[dbInfo.name];
var deferredOperation = dbContext.deferredOperations.pop();
if (deferredOperation) {
deferredOperation.reject(err);
return deferredOperation.promise;
}
}
function _getConnection(dbInfo, upgradeNeeded) {
return new Promise$1((function(resolve, reject) {
dbContexts[dbInfo.name] = dbContexts[dbInfo.name] || createDbContext();
if (dbInfo.db) {
if (upgradeNeeded) {
_deferReadiness(dbInfo);
dbInfo.db.close();
} else {
return resolve(dbInfo.db);
}
}
var dbArgs = [ dbInfo.name ];
if (upgradeNeeded) {
dbArgs.push(dbInfo.version);
}
var openreq = idb.open.apply(idb, dbArgs);
if (upgradeNeeded) {
openreq.onupgradeneeded = function(e) {
var db = openreq.result;
try {
db.createObjectStore(dbInfo.storeName);
if (e.oldVersion <= 1) {
db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);
}
} catch (ex) {
if (ex.name === "ConstraintError") {
console.warn('The database "' + dbInfo.name + '"' + " has been upgraded from version " + e.oldVersion + " to version " + e.newVersion + ', but the storage "' + dbInfo.storeName + '" already exists.');
} else {
throw ex;
}
}
};
}
openreq.onerror = function(e) {
e.preventDefault();
reject(openreq.error);
};
openreq.onsuccess = function() {
var db = openreq.result;
db.onversionchange = function(e) {
e.target.close();
};
resolve(db);
_advanceReadiness(dbInfo);
};
}));
}
function _getOriginalConnection(dbInfo) {
return _getConnection(dbInfo, false);
}
function _getUpgradedConnection(dbInfo) {
return _getConnection(dbInfo, true);
}
function _isUpgradeNeeded(dbInfo, defaultVersion) {
if (!dbInfo.db) {
return true;
}
var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName);
var isDowngrade = dbInfo.version < dbInfo.db.version;
var isUpgrade = dbInfo.version > dbInfo.db.version;
if (isDowngrade) {
if (dbInfo.version !== defaultVersion) {
console.warn('The database "' + dbInfo.name + '"' + " can't be downgraded from version " + dbInfo.db.version + " to version " + dbInfo.version + ".");
}
dbInfo.version = dbInfo.db.version;
}
if (isUpgrade || isNewStore) {
if (isNewStore) {
var incVersion = dbInfo.db.version + 1;
if (incVersion > dbInfo.version) {
dbInfo.version = incVersion;
}
}
return true;
}
return false;
}
function _encodeBlob(blob) {
return new Promise$1((function(resolve, reject) {
var reader = new FileReader;
reader.onerror = reject;
reader.onloadend = function(e) {
var base64 = btoa(e.target.result || "");
resolve({
__local_forage_encoded_blob: true,
data: base64,
type: blob.type
});
};
reader.readAsBinaryString(blob);
}));
}
function _decodeBlob(encodedBlob) {
var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data));
return createBlob([ arrayBuff ], {
type: encodedBlob.type
});
}
function _isEncodedBlob(value) {
return value && value.__local_forage_encoded_blob;
}
function _fullyReady(callback) {
var self = this;
var promise = self._initReady().then((function() {
var dbContext = dbContexts[self._dbInfo.name];
if (dbContext && dbContext.dbReady) {
return dbContext.dbReady;
}
}));
executeTwoCallbacks(promise, callback, callback);
return promise;
}
function _tryReconnect(dbInfo) {
_deferReadiness(dbInfo);
var dbContext = dbContexts[dbInfo.name];
var forages = dbContext.forages;
for (var i = 0; i < forages.length; i++) {
var forage = forages[i];
if (forage._dbInfo.db) {
forage._dbInfo.db.close();
forage._dbInfo.db = null;
}
}
dbInfo.db = null;
return _getOriginalConnection(dbInfo).then((function(db) {
dbInfo.db = db;
if (_isUpgradeNeeded(dbInfo)) {
return _getUpgradedConnection(dbInfo);
}
return db;
})).then((function(db) {
dbInfo.db = dbContext.db = db;
for (var i = 0; i < forages.length; i++) {
forages[i]._dbInfo.db = db;
}
}))["catch"]((function(err) {
_rejectReadiness(dbInfo, err);
throw err;
}));
}
function createTransaction(dbInfo, mode, callback, retries) {
if (retries === undefined) {
retries = 1;
}
try {
var tx = dbInfo.db.transaction(dbInfo.storeName, mode);
callback(null, tx);
} catch (err) {
if (retries > 0 && (!dbInfo.db || err.name === "InvalidStateError" || err.name === "NotFoundError")) {
return Promise$1.resolve().then((function() {
if (!dbInfo.db || err.name === "NotFoundError" && !dbInfo.db.objectStoreNames.contains(dbInfo.storeName) && dbInfo.version <= dbInfo.db.version) {
if (dbInfo.db) {
dbInfo.version = dbInfo.db.version + 1;
}
return _getUpgradedConnection(dbInfo);
}
})).then((function() {
return _tryReconnect(dbInfo).then((function() {
createTransaction(dbInfo, mode, callback, retries - 1);
}));
}))["catch"](callback);
}
callback(err);
}
}
function createDbContext() {
return {
forages: [],
db: null,
dbReady: null,
deferredOperations: []
};
}
function _initStorage(options) {
var self = this;
var dbInfo = {
db: null
};
if (options) {
for (var i in options) {
dbInfo[i] = options[i];
}
}
var dbContext = dbContexts[dbInfo.name];
if (!dbContext) {
dbContext = createDbContext();
dbContexts[dbInfo.name] = dbContext;
}
dbContext.forages.push(self);
if (!self._initReady) {
self._initReady = self.ready;
self.ready = _fullyReady;
}
var initPromises = [];
function ignoreErrors() {
return Promise$1.resolve();
}
for (var j = 0; j < dbContext.forages.length; j++) {
var forage = dbContext.forages[j];
if (forage !== self) {
initPromises.push(forage._initReady()["catch"](ignoreErrors));
}
}
var forages = dbContext.forages.slice(0);
return Promise$1.all(initPromises).then((function() {
dbInfo.db = dbContext.db;
return _getOriginalConnection(dbInfo);
})).then((function(db) {
dbInfo.db = db;
if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) {
return _getUpgradedConnection(dbInfo);
}
return db;
})).then((function(db) {
dbInfo.db = dbContext.db = db;
self._dbInfo = dbInfo;
for (var k = 0; k < forages.length; k++) {
var forage = forages[k];
if (forage !== self) {
forage._dbInfo.db = dbInfo.db;
forage._dbInfo.version = dbInfo.version;
}
}
}));
}
function getItem(key, callback) {
var self = this;
key = normalizeKey(key);
var promise = new Promise$1((function(resolve, reject) {
self.ready().then((function() {
createTransaction(self._dbInfo, READ_ONLY, (function(err, transaction) {
if (err) {
return reject(err);
}
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.get(key);
req.onsuccess = function() {
var value = req.result;
if (value === undefined) {
value = null;
}
if (_isEncodedBlob(value)) {
value = _decodeBlob(value);
}
resolve(value);
};
req.onerror = function() {
reject(req.error);
};
} catch (e) {
reject(e);
}
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function iterate(iterator, callback) {
var self = this;
var promise = new Promise$1((function(resolve, reject) {
self.ready().then((function() {
createTransaction(self._dbInfo, READ_ONLY, (function(err, transaction) {
if (err) {
return reject(err);
}
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.openCursor();
var iterationNumber = 1;
req.onsuccess = function() {
var cursor = req.result;
if (cursor) {
var value = cursor.value;
if (_isEncodedBlob(value)) {
value = _decodeBlob(value);
}
var result = iterator(value, cursor.key, iterationNumber++);
if (result !== void 0) {
resolve(result);
} else {
cursor["continue"]();
}
} else {
resolve();
}
};
req.onerror = function() {
reject(req.error);
};
} catch (e) {
reject(e);
}
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function setItem(key, value, callback) {
var self = this;
key = normalizeKey(key);
var promise = new Promise$1((function(resolve, reject) {
var dbInfo;
self.ready().then((function() {
dbInfo = self._dbInfo;
if (toString.call(value) === "[object Blob]") {
return _checkBlobSupport(dbInfo.db).then((function(blobSupport) {
if (blobSupport) {
return value;
}
return _encodeBlob(value);
}));
}
return value;
})).then((function(value) {
createTransaction(self._dbInfo, READ_WRITE, (function(err, transaction) {
if (err) {
return reject(err);
}
try {
var store = transaction.objectStore(self._dbInfo.storeName);
if (value === null) {
value = undefined;
}
var req = store.put(value, key);
transaction.oncomplete = function() {
if (value === undefined) {
value = null;
}
resolve(value);
};
transaction.onabort = transaction.onerror = function() {
var err = req.error ? req.error : req.transaction.error;
reject(err);
};
} catch (e) {
reject(e);
}
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function removeItem(key, callback) {
var self = this;
key = normalizeKey(key);
var promise = new Promise$1((function(resolve, reject) {
self.ready().then((function() {
createTransaction(self._dbInfo, READ_WRITE, (function(err, transaction) {
if (err) {
return reject(err);
}
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store["delete"](key);
transaction.oncomplete = function() {
resolve();
};
transaction.onerror = function() {
reject(req.error);
};
transaction.onabort = function() {
var err = req.error ? req.error : req.transaction.error;
reject(err);
};
} catch (e) {
reject(e);
}
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function clear(callback) {
var self = this;
var promise = new Promise$1((function(resolve, reject) {
self.ready().then((function() {
createTransaction(self._dbInfo, READ_WRITE, (function(err, transaction) {
if (err) {
return reject(err);
}
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.clear();
transaction.oncomplete = function() {
resolve();
};
transaction.onabort = transaction.onerror = function() {
var err = req.error ? req.error : req.transaction.error;
reject(err);
};
} catch (e) {
reject(e);
}
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function length(callback) {
var self = this;
var promise = new Promise$1((function(resolve, reject) {
self.ready().then((function() {
createTransaction(self._dbInfo, READ_ONLY, (function(err, transaction) {
if (err) {
return reject(err);
}
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.count();
req.onsuccess = function() {
resolve(req.result);
};
req.onerror = function() {
reject(req.error);
};
} catch (e) {
reject(e);
}
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function key(n, callback) {
var self = this;
var promise = new Promise$1((function(resolve, reject) {
if (n < 0) {
resolve(null);
return;
}
self.ready().then((function() {
createTransaction(self._dbInfo, READ_ONLY, (function(err, transaction) {
if (err) {
return reject(err);
}
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var advanced = false;
var req = store.openKeyCursor();
req.onsuccess = function() {
var cursor = req.result;
if (!cursor) {
resolve(null);
return;
}
if (n === 0) {
resolve(cursor.key);
} else {
if (!advanced) {
advanced = true;
cursor.advance(n);
} else {
resolve(cursor.key);
}
}
};
req.onerror = function() {
reject(req.error);
};
} catch (e) {
reject(e);
}
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function keys(callback) {
var self = this;
var promise = new Promise$1((function(resolve, reject) {
self.ready().then((function() {
createTransaction(self._dbInfo, READ_ONLY, (function(err, transaction) {
if (err) {
return reject(err);
}
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.openKeyCursor();
var keys = [];
req.onsuccess = function() {
var cursor = req.result;
if (!cursor) {
resolve(keys);
return;
}
keys.push(cursor.key);
cursor["continue"]();
};
req.onerror = function() {
reject(req.error);
};
} catch (e) {
reject(e);
}
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function dropInstance(options, callback) {
callback = getCallback.apply(this, arguments);
var currentConfig = this.config();
options = typeof options !== "function" && options || {};
if (!options.name) {
options.name = options.name || currentConfig.name;
options.storeName = options.storeName || currentConfig.storeName;
}
var self = this;
var promise;
if (!options.name) {
promise = Promise$1.reject("Invalid arguments");
} else {
var isCurrentDb = options.name === currentConfig.name && self._dbInfo.db;
var dbPromise = isCurrentDb ? Promise$1.resolve(self._dbInfo.db) : _getOriginalConnection(options).then((function(db) {
var dbContext = dbContexts[options.name];
var forages = dbContext.forages;
dbContext.db = db;
for (var i = 0; i < forages.length; i++) {
forages[i]._dbInfo.db = db;
}
return db;
}));
if (!options.storeName) {
promise = dbPromise.then((function(db) {
_deferReadiness(options);
var dbContext = dbContexts[options.name];
var forages = dbContext.forages;
db.close();
for (var i = 0; i < forages.length; i++) {
var forage = forages[i];
forage._dbInfo.db = null;
}
var dropDBPromise = new Promise$1((function(resolve, reject) {
var req = idb.deleteDatabase(options.name);
req.onerror = function() {
var db = req.result;
if (db) {
db.close();
}
reject(req.error);
};
req.onblocked = function() {
console.warn('dropInstance blocked for database "' + options.name + '" until all open connections are closed');
};
req.onsuccess = function() {
var db = req.result;
if (db) {
db.close();
}
resolve(db);
};
}));
return dropDBPromise.then((function(db) {
dbContext.db = db;
for (var i = 0; i < forages.length; i++) {
var _forage = forages[i];
_advanceReadiness(_forage._dbInfo);
}
}))["catch"]((function(err) {
(_rejectReadiness(options, err) || Promise$1.resolve())["catch"]((function() {}));
throw err;
}));
}));
} else {
promise = dbPromise.then((function(db) {
if (!db.objectStoreNames.contains(options.storeName)) {
return;
}
var newVersion = db.version + 1;
_deferReadiness(options);
var dbContext = dbContexts[options.name];
var forages = dbContext.forages;
db.close();
for (var i = 0; i < forages.length; i++) {
var forage = forages[i];
forage._dbInfo.db = null;
forage._dbInfo.version = newVersion;
}
var dropObjectPromise = new Promise$1((function(resolve, reject) {
var req = idb.open(options.name, newVersion);
req.onerror = function(err) {
var db = req.result;
db.close();
reject(err);
};
req.onupgradeneeded = function() {
var db = req.result;
db.deleteObjectStore(options.storeName);
};
req.onsuccess = function() {
var db = req.result;
db.close();
resolve(db);
};
}));
return dropObjectPromise.then((function(db) {
dbContext.db = db;
for (var j = 0; j < forages.length; j++) {
var _forage2 = forages[j];
_forage2._dbInfo.db = db;
_advanceReadiness(_forage2._dbInfo);
}
}))["catch"]((function(err) {
(_rejectReadiness(options, err) || Promise$1.resolve())["catch"]((function() {}));
throw err;
}));
}));
}
}
executeCallback(promise, callback);
return promise;
}
var asyncStorage = {
_driver: "asyncStorage",
_initStorage,
_support: isIndexedDBValid(),
iterate,
getItem,
setItem,
removeItem,
clear,
length,
key,
keys,
dropInstance
};
function isWebSQLValid() {
return typeof openDatabase === "function";
}
var BASE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var BLOB_TYPE_PREFIX = "~~local_forage_type~";
var BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;
var SERIALIZED_MARKER = "__lfsc__:";
var SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length;
var TYPE_ARRAYBUFFER = "arbf";
var TYPE_BLOB = "blob";
var TYPE_INT8ARRAY = "si08";
var TYPE_UINT8ARRAY = "ui08";
var TYPE_UINT8CLAMPEDARRAY = "uic8";
var TYPE_INT16ARRAY = "si16";
var TYPE_INT32ARRAY = "si32";
var TYPE_UINT16ARRAY = "ur16";
var TYPE_UINT32ARRAY = "ui32";
var TYPE_FLOAT32ARRAY = "fl32";
var TYPE_FLOAT64ARRAY = "fl64";
var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;
var toString$1 = Object.prototype.toString;
function stringToBuffer(serializedString) {
var bufferLength = serializedString.length * .75;
var len = serializedString.length;
var i;
var p = 0;
var encoded1, encoded2, encoded3, encoded4;
if (serializedString[serializedString.length - 1] === "=") {
bufferLength--;
if (serializedString[serializedString.length - 2] === "=") {
bufferLength--;
}
}
var buffer = new ArrayBuffer(bufferLength);
var bytes = new Uint8Array(buffer);
for (i = 0; i < len; i += 4) {
encoded1 = BASE_CHARS.indexOf(serializedString[i]);
encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]);
encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]);
encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]);
bytes[p++] = encoded1 << 2 | encoded2 >> 4;
bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;
bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;
}
return buffer;
}
function bufferToString(buffer) {
var bytes = new Uint8Array(buffer);
var base64String = "";
var i;
for (i = 0; i < bytes.length; i += 3) {
base64String += BASE_CHARS[bytes[i] >> 2];
base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];
base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];
base64String += BASE_CHARS[bytes[i + 2] & 63];
}
if (bytes.length % 3 === 2) {
base64String = base64String.substring(0, base64String.length - 1) + "=";
} else if (bytes.length % 3 === 1) {
base64String = base64String.substring(0, base64String.length - 2) + "==";
}
return base64String;
}
function serialize(value, callback) {
var valueType = "";
if (value) {
valueType = toString$1.call(value);
}
if (value && (valueType === "[object ArrayBuffer]" || value.buffer && toString$1.call(value.buffer) === "[object ArrayBuffer]")) {
var buffer;
var marker = SERIALIZED_MARKER;
if (value instanceof ArrayBuffer) {
buffer = value;
marker += TYPE_ARRAYBUFFER;
} else {
buffer = value.buffer;
if (valueType === "[object Int8Array]") {
marker += TYPE_INT8ARRAY;
} else if (valueType === "[object Uint8Array]") {
marker += TYPE_UINT8ARRAY;
} else if (valueType === "[object Uint8ClampedArray]") {
marker += TYPE_UINT8CLAMPEDARRAY;
} else if (valueType === "[object Int16Array]") {
marker += TYPE_INT16ARRAY;
} else if (valueType === "[object Uint16Array]") {
marker += TYPE_UINT16ARRAY;
} else if (valueType === "[object Int32Array]") {
marker += TYPE_INT32ARRAY;
} else if (valueType === "[object Uint32Array]") {
marker += TYPE_UINT32ARRAY;
} else if (valueType === "[object Float32Array]") {
marker += TYPE_FLOAT32ARRAY;
} else if (valueType === "[object Float64Array]") {
marker += TYPE_FLOAT64ARRAY;
} else {
callback(new Error("Failed to get type for BinaryArray"));
}
}
callback(marker + bufferToString(buffer));
} else if (valueType === "[object Blob]") {
var fileReader = new FileReader;
fileReader.onload = function() {
var str = BLOB_TYPE_PREFIX + value.type + "~" + bufferToString(this.result);
callback(SERIALIZED_MARKER + TYPE_BLOB + str);
};
fileReader.readAsArrayBuffer(value);
} else {
try {
callback(JSON.stringify(value));
} catch (e) {
console.error("Couldn't convert value into a JSON string: ", value);
callback(null, e);
}
}
}
function deserialize(value) {
if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) {
return JSON.parse(value);
}
var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);
var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH);
var blobType;
if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {
var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);
blobType = matcher[1];
serializedString = serializedString.substring(matcher[0].length);
}
var buffer = stringToBuffer(serializedString);
switch (type) {
case TYPE_ARRAYBUFFER:
return buffer;
case TYPE_BLOB:
return createBlob([ buffer ], {
type: blobType
});
case TYPE_INT8ARRAY:
return new Int8Array(buffer);
case TYPE_UINT8ARRAY:
return new Uint8Array(buffer);
case TYPE_UINT8CLAMPEDARRAY:
return new Uint8ClampedArray(buffer);
case TYPE_INT16ARRAY:
return new Int16Array(buffer);
case TYPE_UINT16ARRAY:
return new Uint16Array(buffer);
case TYPE_INT32ARRAY:
return new Int32Array(buffer);
case TYPE_UINT32ARRAY:
return new Uint32Array(buffer);
case TYPE_FLOAT32ARRAY:
return new Float32Array(buffer);
case TYPE_FLOAT64ARRAY:
return new Float64Array(buffer);
default:
throw new Error("Unkown type: " + type);
}
}
var localforageSerializer = {
serialize,
deserialize,
stringToBuffer,
bufferToString
};
function createDbTable(t, dbInfo, callback, errorCallback) {
t.executeSql("CREATE TABLE IF NOT EXISTS " + dbInfo.storeName + " " + "(id INTEGER PRIMARY KEY, key unique, value)", [], callback, errorCallback);
}
function _initStorage$1(options) {
var self = this;
var dbInfo = {
db: null
};
if (options) {
for (var i in options) {
dbInfo[i] = typeof options[i] !== "string" ? options[i].toString() : options[i];
}
}
var dbInfoPromise = new Promise$1((function(resolve, reject) {
try {
dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size);
} catch (e) {
return reject(e);
}
dbInfo.db.transaction((function(t) {
createDbTable(t, dbInfo, (function() {
self._dbInfo = dbInfo;
resolve();
}), (function(t, error) {
reject(error);
}));
}), reject);
}));
dbInfo.serializer = localforageSerializer;
return dbInfoPromise;
}
function tryExecuteSql(t, dbInfo, sqlStatement, args, callback, errorCallback) {
t.executeSql(sqlStatement, args, callback, (function(t, error) {
if (error.code === error.SYNTAX_ERR) {
t.executeSql("SELECT name FROM sqlite_master " + "WHERE type='table' AND name = ?", [ dbInfo.storeName ], (function(t, results) {
if (!results.rows.length) {
createDbTable(t, dbInfo, (function() {
t.executeSql(sqlStatement, args, callback, errorCallback);
}), errorCallback);
} else {
errorCallback(t, error);
}
}), errorCallback);
} else {
errorCallback(t, error);
}
}), errorCallback);
}
function getItem$1(key, callback) {
var self = this;
key = normalizeKey(key);
var promise = new Promise$1((function(resolve, reject) {
self.ready().then((function() {
var dbInfo = self._dbInfo;
dbInfo.db.transaction((function(t) {
tryExecuteSql(t, dbInfo, "SELECT * FROM " + dbInfo.storeName + " WHERE key = ? LIMIT 1", [ key ], (function(t, results) {
var result = results.rows.length ? results.rows.item(0).value : null;
if (result) {
result = dbInfo.serializer.deserialize(result);
}
resolve(result);
}), (function(t, error) {
reject(error);
}));
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function iterate$1(iterator, callback) {
var self = this;
var promise = new Promise$1((function(resolve, reject) {
self.ready().then((function() {
var dbInfo = self._dbInfo;
dbInfo.db.transaction((function(t) {
tryExecuteSql(t, dbInfo, "SELECT * FROM " + dbInfo.storeName, [], (function(t, results) {
var rows = results.rows;
var length = rows.length;
for (var i = 0; i < length; i++) {
var item = rows.item(i);
var result = item.value;
if (result) {
result = dbInfo.serializer.deserialize(result);
}
result = iterator(result, item.key, i + 1);
if (result !== void 0) {
resolve(result);
return;
}
}
resolve();
}), (function(t, error) {
reject(error);
}));
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function _setItem(key, value, callback, retriesLeft) {
var self = this;
key = normalizeKey(key);
var promise = new Promise$1((function(resolve, reject) {
self.ready().then((function() {
if (value === undefined) {
value = null;
}
var originalValue = value;
var dbInfo = self._dbInfo;
dbInfo.serializer.serialize(value, (function(value, error) {
if (error) {
reject(error);
} else {
dbInfo.db.transaction((function(t) {
tryExecuteSql(t, dbInfo, "INSERT OR REPLACE INTO " + dbInfo.storeName + " " + "(key, value) VALUES (?, ?)", [ key, value ], (function() {
resolve(originalValue);
}), (function(t, error) {
reject(error);
}));
}), (function(sqlError) {
if (sqlError.code === sqlError.QUOTA_ERR) {
if (retriesLeft > 0) {
resolve(_setItem.apply(self, [ key, originalValue, callback, retriesLeft - 1 ]));
return;
}
reject(sqlError);
}
}));
}
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function setItem$1(key, value, callback) {
return _setItem.apply(this, [ key, value, callback, 1 ]);
}
function removeItem$1(key, callback) {
var self = this;
key = normalizeKey(key);
var promise = new Promise$1((function(resolve, reject) {
self.ready().then((function() {
var dbInfo = self._dbInfo;
dbInfo.db.transaction((function(t) {
tryExecuteSql(t, dbInfo, "DELETE FROM " + dbInfo.storeName + " WHERE key = ?", [ key ], (function() {
resolve();
}), (function(t, error) {
reject(error);
}));
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function clear$1(callback) {
var self = this;
var promise = new Promise$1((function(resolve, reject) {
self.ready().then((function() {
var dbInfo = self._dbInfo;
dbInfo.db.transaction((function(t) {
tryExecuteSql(t, dbInfo, "DELETE FROM " + dbInfo.storeName, [], (function() {
resolve();
}), (function(t, error) {
reject(error);
}));
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function length$1(callback) {
var self = this;
var promise = new Promise$1((function(resolve, reject) {
self.ready().then((function() {
var dbInfo = self._dbInfo;
dbInfo.db.transaction((function(t) {
tryExecuteSql(t, dbInfo, "SELECT COUNT(key) as c FROM " + dbInfo.storeName, [], (function(t, results) {
var result = results.rows.item(0).c;
resolve(result);
}), (function(t, error) {
reject(error);
}));
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function key$1(n, callback) {
var self = this;
var promise = new Promise$1((function(resolve, reject) {
self.ready().then((function() {
var dbInfo = self._dbInfo;
dbInfo.db.transaction((function(t) {
tryExecuteSql(t, dbInfo, "SELECT key FROM " + dbInfo.storeName + " WHERE id = ? LIMIT 1", [ n + 1 ], (function(t, results) {
var result = results.rows.length ? results.rows.item(0).key : null;
resolve(result);
}), (function(t, error) {
reject(error);
}));
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function keys$1(callback) {
var self = this;
var promise = new Promise$1((function(resolve, reject) {
self.ready().then((function() {
var dbInfo = self._dbInfo;
dbInfo.db.transaction((function(t) {
tryExecuteSql(t, dbInfo, "SELECT key FROM " + dbInfo.storeName, [], (function(t, results) {
var keys = [];
for (var i = 0; i < results.rows.length; i++) {
keys.push(results.rows.item(i).key);
}
resolve(keys);
}), (function(t, error) {
reject(error);
}));
}));
}))["catch"](reject);
}));
executeCallback(promise, callback);
return promise;
}
function getAllStoreNames(db) {
return new Promise$1((function(resolve, reject) {
db.transaction((function(t) {
t.executeSql("SELECT name FROM sqlite_master " + "WHERE type='table' AND name <> '__WebKitDatabaseInfoTable__'", [], (function(t, results) {
var storeNames = [];
for (var i = 0; i < results.rows.length; i++) {
storeNames.push(results.rows.item(i).name);
}
resolve({
db,
storeNames
});
}), (function(t, error) {
reject(error);
}));
}), (function(sqlError) {
reject(sqlError);
}));
}));
}
function dropInstance$1(options, callback) {
callback = getCallback.apply(this, arguments);
var currentConfig = this.config();
options = typeof options !== "function" && options || {};
if (!options.name) {
options.name = options.name || currentConfig.name;
options.storeName = options.storeName || currentConfig.storeName;
}
var self = this;
var promise;
if (!options.name) {
promise = Promise$1.reject("Invalid arguments");
} else {
promise = new Promise$1((function(resolve) {
var db;
if (options.name === currentConfig.name) {
db = self._dbInfo.db;
} else {
db = openDatabase(options.name, "", "", 0);
}
if (!options.storeName) {
resolve(getAllStoreNames(db));
} else {
resolve({
db,
storeNames: [ options.storeName ]
});
}
})).then((function(operationInfo) {
return new Promise$1((function(resolve, reject) {
operationInfo.db.transaction((function(t) {
function dropTable(storeName) {
return new Promise$1((function(resolve, reject) {
t.executeSql("DROP TABLE IF EXISTS " + storeName, [], (function() {
resolve();
}), (function(t, error) {
reject(error);
}));
}));
}
var operations = [];
for (var i = 0, len = operationInfo.storeNames.length; i < len; i++) {
operations.push(dropTable(operationInfo.storeNames[i]));
}
Promise$1.all(operations).then((function() {
resolve();
}))["catch"]((function(e) {
reject(e);
}));
}), (function(sqlError) {
reject(sqlError);
}));
}));
}));
}
executeCallback(promise, callback);
return promise;
}
var webSQLStorage = {
_driver: "webSQLStorage",
_initStorage: _initStorage$1,
_support: isWebSQLValid(),
iterate: iterate$1,
getItem: getItem$1,
setItem: setItem$1,
removeItem: removeItem$1,
clear: clear$1,
length: length$1,
key: key$1,
keys: keys$1,
dropInstance: dropInstance$1
};
function isLocalStorageValid() {
try {
return typeof localStorage !== "undefined" && "setItem" in localStorage && !!localStorage.setItem;
} catch (e) {
return false;
}
}
function _getKeyPrefix(options, defaultConfig) {
var keyPrefix = options.name + "/";
if (options.storeName !== defaultConfig.storeName) {
keyPrefix += options.storeName + "/";
}
return keyPrefix;
}
function checkIfLocalStorageThrows() {
var localStorageTestKey = "_localforage_support_test";
try {
localStorage.setItem(localStorageTestKey, true);
localStorage.removeItem(localStorageTestKey);
return false;
} catch (e) {
return true;
}
}
function _isLocalStorageUsable() {
return !checkIfLocalStorageThrows() || localStorage.length > 0;
}
function _initStorage$2(options) {
var self = this;
var dbInfo = {};
if (options) {
for (var i in options) {
dbInfo[i] = options[i];
}
}
dbInfo.keyPrefix = _getKeyPrefix(options, self._defaultConfig);
if (!_isLocalStorageUsable()) {
return Promise$1.reject();
}
self._dbInfo = dbInfo;
dbInfo.serializer = localforageSerializer;
return Promise$1.resolve();
}
function clear$2(callback) {
var self = this;
var promise = self.ready().then((function() {
var keyPrefix = self._dbInfo.keyPrefix;
for (var i = localStorage.length - 1; i >= 0; i--) {
var key = localStorage.key(i);
if (key.indexOf(keyPrefix) === 0) {
localStorage.removeItem(key);
}
}
}));
executeCallback(promise, callback);
return promise;
}
function getItem$2(key, callback) {
var self = this;
key = normalizeKey(key);
var promise = self.ready().then((function() {
var dbInfo = self._dbInfo;
var result = localStorage.getItem(dbInfo.keyPrefix + key);
if (result) {
result = dbInfo.serializer.deserialize(result);
}
return result;
}));
executeCallback(promise, callback);
return promise;
}
function iterate$2(iterator, callback) {
var self = this;
var promise = self.ready().then((function() {
var dbInfo = self._dbInfo;
var keyPrefix = dbInfo.keyPrefix;
var keyPrefixLength = keyPrefix.length;
var length = localStorage.length;
var iterationNumber = 1;
for (var i = 0; i < length; i++) {
var key = localStorage.key(i);
if (key.indexOf(keyPrefix) !== 0) {
continue;
}
var value = localStorage.getItem(key);
if (value) {
value = dbInfo.serializer.deserialize(value);
}
value = iterator(value, key.substring(keyPrefixLength), iterationNumber++);
if (value !== void 0) {
return value;
}
}
}));
executeCallback(promise, callback);
return promise;
}
function key$2(n, callback) {
var self = this;
var promise = self.ready().then((function() {
var dbInfo = self._dbInfo;
var result;
try {
result = localStorage.key(n);
} catch (error) {
result = null;
}
if (result) {
result = result.substring(dbInfo.keyPrefix.length);
}
return result;
}));
executeCallback(promise, callback);
return promise;
}
function keys$2(callback) {
var self = this;
var promise = self.ready().then((function() {
var dbInfo = self._dbInfo;
var length = localStorage.length;
var keys = [];
for (var i = 0; i < length; i++) {
var itemKey = localStorage.key(i);
if (itemKey.indexOf(dbInfo.keyPrefix) === 0) {
keys.push(itemKey.substring(dbInfo.keyPrefix.length));
}
}
return keys;
}));
executeCallback(promise, callback);
return promise;
}
function length$2(callback) {
var self = this;
var promise = self.keys().then((function(keys) {
return keys.length;
}));
executeCallback(promise, callback);
return promise;
}
function removeItem$2(key, callback) {
var self = this;
key = normalizeKey(key);
var promise = self.ready().then((function() {
var dbInfo = self._dbInfo;
localStorage.removeItem(dbInfo.keyPrefix + key);
}));
executeCallback(promise, callback);
return promise;
}
function setItem$2(key, value, callback) {
var self = this;
key = normalizeKey(key);
var promise = self.ready().then((function() {
if (value === undefined) {
value = null;
}
var originalValue = value;
return new Promise$1((function(resolve, reject) {
var dbInfo = self._dbInfo;
dbInfo.serializer.serialize(value, (function(value, error) {
if (error) {
reject(error);
} else {
try {
localStorage.setItem(dbInfo.keyPrefix + key, value);
resolve(originalValue);
} catch (e) {
if (e.name === "QuotaExceededError" || e.name === "NS_ERROR_DOM_QUOTA_REACHED") {
reject(e);
}
reject(e);
}
}
}));
}));
}));
executeCallback(promise, callback);
return promise;
}
function dropInstance$2(options, callback) {
callback = getCallback.apply(this, arguments);
options = typeof options !== "function" && options || {};
if (!options.name) {
var currentConfig = this.config();
options.name = options.name || currentConfig.name;
options.storeName = options.storeName || currentConfig.storeName;
}
var self = this;
var promise;
if (!options.name) {
promise = Promise$1.reject("Invalid arguments");
} else {
promise = new Promise$1((function(resolve) {
if (!options.storeName) {
resolve(options.name + "/");
} else {
resolve(_getKeyPrefix(options, self._defaultConfig));
}
})).then((function(keyPrefix) {
for (var i = localStorage.length - 1; i >= 0; i--) {
var key = localStorage.key(i);
if (key.indexOf(keyPrefix) === 0) {
localStorage.removeItem(key);
}
}
}));
}
executeCallback(promise, callback);
return promise;
}
var localStorageWrapper = {
_driver: "localStorageWrapper",
_initStorage: _initStorage$2,
_support: isLocalStorageValid(),
iterate: iterate$2,
getItem: getItem$2,
setItem: setItem$2,
removeItem: removeItem$2,
clear: clear$2,
length: length$2,
key: key$2,
keys: keys$2,
dropInstance: dropInstance$2
};
var sameValue = function sameValue(x, y) {
return x === y || typeof x === "number" && typeof y === "number" && isNaN(x) && isNaN(y);
};
var includes = function includes(array, searchElement) {
var len = array.length;
var i = 0;
while (i < len) {
if (sameValue(array[i], searchElement)) {
return true;
}
i++;
}
return false;
};
var isArray = Array.isArray || function(arg) {
return Object.prototype.toString.call(arg) === "[object Array]";
};
var DefinedDrivers = {};
var DriverSupport = {};
var DefaultDrivers = {
INDEXEDDB: asyncStorage,
WEBSQL: webSQLStorage,
LOCALSTORAGE: localStorageWrapper
};
var DefaultDriverOrder = [ DefaultDrivers.INDEXEDDB._driver, DefaultDrivers.WEBSQL._driver, DefaultDrivers.LOCALSTORAGE._driver ];
var OptionalDriverMethods = [ "dropInstance" ];
var LibraryMethods = [ "clear", "getItem", "iterate", "key", "keys", "length", "removeItem", "setItem" ].concat(OptionalDriverMethods);
var DefaultConfig = {
description: "",
driver: DefaultDriverOrder.slice(),
name: "localforage",
size: 4980736,
storeName: "keyvaluepairs",
version: 1
};
function callWhenReady(localForageInstance, libraryMethod) {
localForageInstance[libraryMethod] = function() {
var _args = arguments;
return localForageInstance.ready().then((function() {
return localForageInstance[libraryMethod].apply(localForageInstance, _args);
}));
};
}
function extend() {
for (var i = 1; i < arguments.length; i++) {
var arg = arguments[i];
if (arg) {
for (var _key in arg) {
if (arg.hasOwnProperty(_key)) {
if (isArray(arg[_key])) {
arguments[0][_key] = arg[_key].slice();
} else {
arguments[0][_key] = arg[_key];
}
}
}
}
}
return arguments[0];
}
var LocalForage = function() {
function LocalForage(options) {
_classCallCheck(this, LocalForage);
for (var driverTypeKey in DefaultDrivers) {
if (DefaultDrivers.hasOwnProperty(driverTypeKey)) {
var driver = DefaultDrivers[driverTypeKey];
var driverName = driver._driver;
this[driverTypeKey] = driverName;
if (!DefinedDrivers[driverName]) {
this.defineDriver(driver);
}
}
}
this._defaultConfig = extend({}, DefaultConfig);
this._config = extend({}, this._defaultConfig, options);
this._driverSet = null;
this._initDriver = null;
this._ready = false;
this._dbInfo = null;
this._wrapLibraryMethodsWithReady();
this.setDriver(this._config.driver)["catch"]((function() {}));
}
LocalForage.prototype.config = function config(options) {
if ((typeof options === "undefined" ? "undefined" : _typeof(options)) === "object") {
if (this._ready) {
return new Error("Can't call config() after localforage " + "has been used.");
}
for (var i in options) {
if (i === "storeName") {
options[i] = options[i].replace(/\W/g, "_");
}
if (i === "version" && typeof options[i] !== "number") {
return new Error("Database version must be a number.");
}
this._config[i] = options[i];
}
if ("driver" in options && options.driver) {
return this.setDriver(this._config.driver);
}
return true;
} else if (typeof options === "string") {
return this._config[options];
} else {
return this._config;
}
};
LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) {
var promise = new Promise$1((function(resolve, reject) {
try {
var driverName = driverObject._driver;
var complianceError = new Error("Custom driver not compliant; see " + "https://mozilla.github.io/localForage/#definedriver");
if (!driverObject._driver) {
reject(complianceError);
return;
}
var driverMethods = LibraryMethods.concat("_initStorage");
for (var i = 0, len = driverMethods.length; i < len; i++) {
var driverMethodName = driverMethods[i];
var isRequired = !includes(OptionalDriverMethods, driverMethodName);
if ((isRequired || driverObject[driverMethodName]) && typeof driverObject[driverMethodName] !== "function") {
reject(complianceError);
return;
}
}
var configureMissingMethods = function configureMissingMethods() {
var methodNotImplementedFactory = function methodNotImplementedFactory(methodName) {
return function() {
var error = new Error("Method " + methodName + " is not implemented by the current driver");
var promise = Promise$1.reject(error);
executeCallback(promise, arguments[arguments.length - 1]);
return promise;
};
};
for (var _i = 0, _len = OptionalDriverMethods.length; _i < _len; _i++) {
var optionalDriverMethod = OptionalDriverMethods[_i];
if (!driverObject[optionalDriverMethod]) {
driverObject[optionalDriverMethod] = methodNotImplementedFactory(optionalDriverMethod);
}
}
};
configureMissingMethods();
var setDriverSupport = function setDriverSupport(support) {
if (DefinedDrivers[driverName]) {
console.info("Redefining LocalForage driver: " + driverName);
}
DefinedDrivers[driverName] = driverObject;
DriverSupport[driverName] = support;
resolve();
};
if ("_support" in driverObject) {
if (driverObject._support && typeof driverObject._support === "function") {
driverObject._support().then(setDriverSupport, reject);
} else {
setDriverSupport(!!driverObject._support);
}
} else {
setDriverSupport(true);
}
} catch (e) {
reject(e);
}
}));
executeTwoCallbacks(promise, callback, errorCallback);
return promise;
};
LocalForage.prototype.driver = function driver() {
return this._driver || null;
};
LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) {
var getDriverPromise = DefinedDrivers[driverName] ? Promise$1.resolve(DefinedDrivers[driverName]) : Promise$1.reject(new Error("Driver not found."));
executeTwoCallbacks(getDriverPromise, callback, errorCallback);
return getDriverPromise;
};
LocalForage.prototype.getSerializer = function getSerializer(callback) {
var serializerPromise = Promise$1.resolve(localforageSerializer);
executeTwoCallbacks(serializerPromise, callback);
return serializerPromise;
};
LocalForage.prototype.ready = function ready(callback) {
var self = this;
var promise = self._driverSet.then((function() {
if (self._ready === null) {
self._ready = self._initDriver();
}
return self._ready;
}));
executeTwoCallbacks(promise, callback, callback);
return promise;
};
LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) {
var self = this;
if (!isArray(drivers)) {
drivers = [ drivers ];
}
var supportedDrivers = this._getSupportedDrivers(drivers);
function setDriverToConfig() {
self._config.driver = self.driver();
}
function extendSelfWithDriver(driver) {
self._extend(driver);
setDriverToConfig();
self._ready = self._initStorage(self._config);
return self._ready;
}
function initDriver(supportedDrivers) {
return function() {
var currentDriverIndex = 0;
function driverPromiseLoop() {
while (currentDriverIndex < supportedDrivers.length) {
var driverName = supportedDrivers[currentDriverIndex];
currentDriverIndex++;
self._dbInfo = null;
self._ready = null;
return self.getDriver(driverName).then(extendSelfWithDriver)["catch"](driverPromiseLoop);
}
setDriverToConfig();
var error = new Error("No available storage method found.");
self._driverSet = Promise$1.reject(error);
return self._driverSet;
}
return driverPromiseLoop();
};
}
var oldDriverSetDone = this._driverSet !== null ? this._driverSet["catch"]((function() {
return Promise$1.resolve();
})) : Promise$1.resolve();
this._driverSet = oldDriverSetDone.then((function() {
var driverName = supportedDrivers[0];
self._dbInfo = null;
self._ready = null;
return self.getDriver(driverName).then((function(driver) {
self._driver = driver._driver;
setDriverToConfig();
self._wrapLibraryMethodsWithReady();
self._initDriver = initDriver(supportedDrivers);
}));
}))["catch"]((function() {
setDriverToConfig();
var error = new Error("No available storage method found.");
self._driverSet = Promise$1.reject(error);
return self._driverSet;
}));
executeTwoCallbacks(this._driverSet, callback, errorCallback);
return this._driverSet;
};
LocalForage.prototype.supports = function supports(driverName) {
return !!DriverSupport[driverName];
};
LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) {
extend(this, libraryMethodsAndProperties);
};
LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) {
var supportedDrivers = [];
for (var i = 0, len = drivers.length; i < len; i++) {
var driverName = drivers[i];
if (this.supports(driverName)) {
supportedDrivers.push(driverName);
}
}
return supportedDrivers;
};
LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() {
for (var i = 0, len = LibraryMethods.length; i < len; i++) {
callWhenReady(this, LibraryMethods[i]);
}
};
LocalForage.prototype.createInstance = function createInstance(options) {
return new LocalForage(options);
};
return LocalForage;
}();
var localforage_js = new LocalForage;
module.exports = localforage_js;
}, {
3: 3
} ]
}, {}, [ 4 ])(4);
}));
})(localforage);
return localforage.exports;
}
var hasRequiredCacheStore;
function requireCacheStore() {
if (hasRequiredCacheStore) return cacheStore$1.exports;
hasRequiredCacheStore = 1;
(function(module) {
(() => {
const factory = (Util, localForage) => {
let window = globalThis;
let self = globalThis;
var S = window.CryptPad_Cache = {};
var onReady = Util.mkEvent(true);
var allowed = false;
var disabled = false;
var supported = false;
try {
var request = window.indexedDB.open("test_db", 1);
request.onsuccess = function() {
supported = true;
allowed = supported && !disabled;
onReady.fire();
};
request.onerror = function() {
onReady.fire();
};
} catch (e) {
onReady.fire();
}
S.enable = function() {
disabled = false;
allowed = supported && !disabled;
};
S.disable = function() {
disabled = true;
allowed = supported && !disabled;
};
S.isEnabled = () => allowed;
var cache = localForage.createInstance({
driver: localForage.INDEXEDDB,
name: "cp_cache"
});
S.getBlobCache = function(id, cb) {
cb = Util.once(Util.mkAsync(cb || function() {}));
onReady.reg((function() {
if (!allowed) {
return void cb("NOCACHE");
}
cache.getItem(id, (function(err, obj) {
if (err || !obj || !obj.c) {
return void cb(Util.serializeError(err || "EINVAL"));
}
cb(null, obj.c);
obj.t = +new Date;
cache.setItem(id, obj, (function(err) {
if (!err) {
return;
}
console.error(err);
}));
}));
}));
};
S.setBlobCache = function(id, u8, cb) {
cb = Util.once(Util.mkAsync(cb || function() {}));
onReady.reg((function() {
if (!allowed) {
return void cb("NOCACHE");
}
if (!u8) {
return void cb("EINVAL");
}
cache.setItem(id, {
c: u8,
t: +new Date
}, (function(err) {
cb(Util.serializeError(err));
}));
}));
};
S.getChannelCache = function(id, cb) {
cb = Util.once(Util.mkAsync(cb || function() {}));
onReady.reg((function() {
if (!allowed) {
return void cb("NOCACHE");
}
cache.getItem(id, (function(err, obj) {
if (err || !obj || !Array.isArray(obj.c)) {
return void cb(Util.serializeError(err || "EINVAL"));
}
cb(null, obj);
obj.t = +new Date;
cache.setItem(id, obj, (function(err) {
if (!err) {
return;
}
console.error(err);
}));
}));
}));
};
var checkCheckpoints = function(array) {
if (!Array.isArray(array)) {
return;
}
if (array.length > 100) {
array.splice(0, array.length - 100);
}
var firstCpIdx;
array.some((function(el, i) {
if (!el.isCheckpoint) {
return;
}
firstCpIdx = i;
return true;
}));
array.splice(0, firstCpIdx);
};
var t = {};
S.storeCache = function(id, validateKey, val, onError) {
onError = Util.once(Util.mkAsync(onError || function() {}));
onReady.reg((function() {
t[id] = t[id] || Util.throttle((function(validateKey, val, onError) {
if (!allowed) {
return void onError("NOCACHE");
}
if (!Array.isArray(val) || !validateKey) {
return void onError("EINVAL");
}
checkCheckpoints(val);
cache.setItem(id, {
k: validateKey,
c: val,
t: +new Date
}, (function(err) {
if (err) {
onError(Util.serializeError(err));
}
}));
}), 50);
t[id](validateKey, val, onError);
}));
};
S.leaveChannel = function(id) {
delete t[id];
};
S.clearChannel = function(id, cb) {
cb = Util.once(Util.mkAsync(cb || function() {}));
onReady.reg((function() {
if (!allowed) {
return void cb("NOCACHE");
}
cache.removeItem(id, (function() {
cb();
}));
}));
};
S.clear = function(cb) {
cb = Util.once(Util.mkAsync(cb || function() {}));
onReady.reg((function() {
if (!allowed) {
return void cb("NOCACHE");
}
cache.clear(cb);
}));
};
S.getKeys = function(cb) {
cb = Util.once(Util.mkAsync(cb || function() {}));
onReady.reg((function() {
if (!allowed) {
return void cb("NOCACHE");
}
cache.keys().then((function(keys) {
cb(null, keys);
})).catch((function(err) {
cb(err);
}));
}));
};
S.getTime = function(id, cb) {
cb = Util.once(Util.mkAsync(cb || function() {}));
onReady.reg((function() {
if (!allowed) {
return void cb("NOCACHE");
}
cache.getItem(id, (function(err, obj) {
if (err || !obj || !obj.c) {
return void cb(Util.serializeError(err || "EINVAL"));
}
cb(null, obj.t);
}));
}));
};
self.CryptPad_clearIndexedDB = S.clear;
return S;
};
if (module.exports) {
module.exports = factory(requireCommonUtil(), requireLocalforage());
}
})();
})(cacheStore$1);
return cacheStore$1.exports;
}
var cacheStoreExports = requireCacheStore();
var cacheStore = getDefaultExportFromCjs(cacheStoreExports);
var Cache = _mergeNamespaces({
__proto__: null,
default: cacheStore
}, [ cacheStoreExports ]);
const onCacheReadyEvt$1 = commonUtilExports.mkEvent(true);
const onReadyEvt$1 = commonUtilExports.mkEvent(true);
const onDisconnectEvt$1 = commonUtilExports.mkEvent();
const onReconnectEvt$1 = commonUtilExports.mkEvent();
let ApiConfig = {};
const init$1 = config => {
var _a, _b;
const {broadcast, userHash, anonHash} = config;
const hash = userHash || anonHash || commonHashExports.createRandomHash("drive");
const store = config.store;
const updateProgress = function(data) {
data.type = "drive";
broadcast([], "LOADING_DRIVE", data);
};
const secret = commonHashExports.getSecrets("drive", hash);
const listmapConfig = {
data: {},
websocketURL: networkConfigExports.getWebsocketURL(),
network: (_a = config.store) === null || _a === void 0 ? void 0 : _a.network,
channel: secret.channel,
readOnly: false,
validateKey: ((_b = secret.keys) === null || _b === void 0 ? void 0 : _b.validateKey) || undefined,
crypto: cryptoExports.createEncryptor(secret.keys),
Cache,
userName: "fs",
logLevel: 1,
ChainPad,
updateProgress,
classic: true
};
const rt = globalThis.CP_account_rt = chainpadListmapExports.create(listmapConfig);
store.driveSecret = secret;
store.proxy = rt.proxy;
store.onRpcReadyEvt = commonUtilExports.mkEvent(true);
store.loggedIn = typeof config.userHash !== "undefined";
const returned = {
loggedIn: store.loggedIn
};
rt.proxy.on("create", (function(info) {
store.realtime = info.realtime;
store.network = info.network;
if (!store.loggedIn) {
returned.anonHash = commonHashExports.getEditHashFromKeys(secret);
}
})).on("cacheready", (function(info) {
store.realtime = info.realtime;
store.offline = true;
store.networkPromise = info.networkPromise;
store.cacheReturned = returned;
if (store.networkPromise && store.networkPromise.then) {
const to = setTimeout((function() {
store.networkTimeout = true;
broadcast([], "LOADING_DRIVE", {
type: "offline"
});
}), 5e3);
store.networkPromise.then((function(network) {
store.network || (store.network = network);
clearTimeout(to);
}), (function(err) {
console.error(err);
clearTimeout(to);
}));
}
if (!config.cache) {
return;
}
returned.edPublic = rt.proxy.edPublic;
onCacheReadyEvt$1.fire(returned);
})).on("ready", (function(info) {
delete store.networkTimeout;
if (store.ready) {
return;
}
store.driveMetadata = info.metadata;
if (!rt.proxy.drive) {
rt.proxy.drive = {};
}
if (!rt.proxy[commonConstantsExports.displayNameKey] && store.noDriveName) {
rt.proxy[commonConstantsExports.displayNameKey] = store.noDriveName;
}
if (!rt.proxy.uid && store.noDriveUid) {
rt.proxy.uid = store.noDriveUid;
}
if (!rt.proxy.form_seed && config.form_seed) {
rt.proxy.form_seed = config.form_seed;
}
if (rt.proxy.edPublic && Array.isArray(ApiConfig.adminKeys) && ApiConfig.adminKeys.indexOf(rt.proxy.edPublic) !== -1) {
store.isAdmin = true;
}
returned.edPublic = rt.proxy.edPublic;
onReadyEvt$1.fire(returned);
})).on("error", (function(info) {
if (info.error !== "EDELETED") {
return;
}
if (store.ownDeletion) {
return;
}
store.isDeleted = true;
broadcast([], "DRIVE_DELETED", info.message);
})).on("disconnect", (function() {
store.offline = true;
onDisconnectEvt$1.fire();
broadcast([], "UPDATE_METADATA");
})).on("reconnect", (function() {
store.offline = false;
onReconnectEvt$1.fire();
broadcast([], "UPDATE_METADATA");
}));
return {
channel: secret.channel,
onAccountCacheReady: onCacheReadyEvt$1.reg,
onAccountReady: onReadyEvt$1.reg,
onDisconnect: onDisconnectEvt$1.reg,
onReconnect: onReconnectEvt$1.reg
};
};
const Account = {
setCustomize: data => {
ApiConfig = data.ApiConfig;
},
init: init$1
};
var account = Object.freeze({
__proto__: null,
Account
});
var commonFeedback$1 = {
exports: {}
};
var hasRequiredCommonFeedback;
function requireCommonFeedback() {
if (hasRequiredCommonFeedback) return commonFeedback$1.exports;
hasRequiredCommonFeedback = 1;
(function(module) {
(() => {
const factory = (AppConfig = {}, Messages = {}) => {
var Feedback = {};
Feedback.setCustomize = data => {
Messages = data.Messages;
AppConfig = data.AppConfig;
};
Feedback.init = function(state) {
Feedback.state = state;
};
var randomToken = function() {
return Math.random().toString(16).replace(/0./, "");
};
var ajax = function(url, cb) {
var http = new XMLHttpRequest;
http.open("HEAD", url);
http.onreadystatechange = function() {
if (this.readyState === this.DONE) {
if (cb) {
cb();
}
}
};
http.send();
};
Feedback.send = function(action, force, cb) {
if (typeof cb !== "function") {
cb = function() {};
}
if (AppConfig.disableFeedback) {
return void cb();
}
if (!action) {
return void cb();
}
if (force !== true) {
if (!Feedback.state) {
return void cb();
}
}
var href = "/common/feedback.html?" + action + "=" + randomToken();
ajax(href, cb);
};
Feedback.reportAppUsage = function() {
var pattern = window.location.pathname.split("/").filter((function(x) {
return x;
})).join(".");
if (/^#\/1\/view\//.test(window.location.hash)) {
Feedback.send(pattern + "_VIEW");
} else {
Feedback.send(pattern);
}
};
Feedback.reportScreenDimensions = function() {
var h = window.innerHeight;
var w = window.innerWidth;
Feedback.send("DIMENSIONS:" + h + "x" + w);
};
Feedback.reportLanguage = function() {
if (!Messages) {
return;
}
Feedback.send("LANG_" + Messages._languageUsed);
};
return Feedback;
};
if (module.exports) {
module.exports = factory(undefined, undefined);
}
})();
})(commonFeedback$1);
return commonFeedback$1.exports;
}
var commonFeedbackExports = requireCommonFeedback();
var commonFeedback = getDefaultExportFromCjs(commonFeedbackExports);
var Feedback = _mergeNamespaces({
__proto__: null,
default: commonFeedback
}, [ commonFeedbackExports ]);
var commonCredential$1 = {
exports: {}
};
var scryptAsync = {
exports: {}
};
/*!
* Fast "async" scrypt implementation in JavaScript.
* Copyright (c) 2013-2015 Dmitry Chestnykh | BSD License
* https://github.com/dchest/scrypt-async-js
*/ var hasRequiredScryptAsync;
function requireScryptAsync() {
if (hasRequiredScryptAsync) return scryptAsync.exports;
hasRequiredScryptAsync = 1;
(function(module) {
function scrypt(password, salt, logN, r, dkLen, interruptStep, callback, encoding) {
function SHA256(m) {
var K = [ 1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221, 3624381080, 310598401, 607225278, 1426881987, 1925078388, 2162078206, 2614888103, 3248222580, 3835390401, 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, 2554220882, 2821834349, 2952996808, 3210313671, 3336571891, 3584528711, 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, 2456956037, 2730485921, 2820302411, 3259730800, 3345764771, 3516065817, 3600352804, 4094571909, 275423344, 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, 1955562222, 2024104815, 2227730452, 2361852424, 2428436474, 2756734187, 3204031479, 3329325298 ];
var h0 = 1779033703, h1 = 3144134277, h2 = 1013904242, h3 = 2773480762, h4 = 1359893119, h5 = 2600822924, h6 = 528734635, h7 = 1541459225, w = new Array(64);
function blocks(p) {
var off = 0, len = p.length;
while (len >= 64) {
var a = h0, b = h1, c = h2, d = h3, e = h4, f = h5, g = h6, h = h7, u, i, j, t1, t2;
for (i = 0; i < 16; i++) {
j = off + i * 4;
w[i] = (p[j] & 255) << 24 | (p[j + 1] & 255) << 16 | (p[j + 2] & 255) << 8 | p[j + 3] & 255;
}
for (i = 16; i < 64; i++) {
u = w[i - 2];
t1 = (u >>> 17 | u << 32 - 17) ^ (u >>> 19 | u << 32 - 19) ^ u >>> 10;
u = w[i - 15];
t2 = (u >>> 7 | u << 32 - 7) ^ (u >>> 18 | u << 32 - 18) ^ u >>> 3;
w[i] = (t1 + w[i - 7] | 0) + (t2 + w[i - 16] | 0) | 0;
}
for (i = 0; i < 64; i++) {
t1 = (((e >>> 6 | e << 32 - 6) ^ (e >>> 11 | e << 32 - 11) ^ (e >>> 25 | e << 32 - 25)) + (e & f ^ ~e & g) | 0) + (h + (K[i] + w[i] | 0) | 0) | 0;
t2 = ((a >>> 2 | a << 32 - 2) ^ (a >>> 13 | a << 32 - 13) ^ (a >>> 22 | a << 32 - 22)) + (a & b ^ a & c ^ b & c) | 0;
h = g;
g = f;
f = e;
e = d + t1 | 0;
d = c;
c = b;
b = a;
a = t1 + t2 | 0;
}
h0 = h0 + a | 0;
h1 = h1 + b | 0;
h2 = h2 + c | 0;
h3 = h3 + d | 0;
h4 = h4 + e | 0;
h5 = h5 + f | 0;
h6 = h6 + g | 0;
h7 = h7 + h | 0;
off += 64;
len -= 64;
}
}
blocks(m);
var i, bytesLeft = m.length % 64, bitLenHi = m.length / 536870912 | 0, bitLenLo = m.length << 3, numZeros = bytesLeft < 56 ? 56 : 120, p = m.slice(m.length - bytesLeft, m.length);
p.push(128);
for (i = bytesLeft + 1; i < numZeros; i++) p.push(0);
p.push(bitLenHi >>> 24 & 255);
p.push(bitLenHi >>> 16 & 255);
p.push(bitLenHi >>> 8 & 255);
p.push(bitLenHi >>> 0 & 255);
p.push(bitLenLo >>> 24 & 255);
p.push(bitLenLo >>> 16 & 255);
p.push(bitLenLo >>> 8 & 255);
p.push(bitLenLo >>> 0 & 255);
blocks(p);
return [ h0 >>> 24 & 255, h0 >>> 16 & 255, h0 >>> 8 & 255, h0 >>> 0 & 255, h1 >>> 24 & 255, h1 >>> 16 & 255, h1 >>> 8 & 255, h1 >>> 0 & 255, h2 >>> 24 & 255, h2 >>> 16 & 255, h2 >>> 8 & 255, h2 >>> 0 & 255, h3 >>> 24 & 255, h3 >>> 16 & 255, h3 >>> 8 & 255, h3 >>> 0 & 255, h4 >>> 24 & 255, h4 >>> 16 & 255, h4 >>> 8 & 255, h4 >>> 0 & 255, h5 >>> 24 & 255, h5 >>> 16 & 255, h5 >>> 8 & 255, h5 >>> 0 & 255, h6 >>> 24 & 255, h6 >>> 16 & 255, h6 >>> 8 & 255, h6 >>> 0 & 255, h7 >>> 24 & 255, h7 >>> 16 & 255, h7 >>> 8 & 255, h7 >>> 0 & 255 ];
}
function PBKDF2_HMAC_SHA256_OneIter(password, salt, dkLen) {
password = password.length <= 64 ? password : SHA256(password);
var i, innerLen = 64 + salt.length + 4, inner = new Array(innerLen), outerKey = new Array(64), dk = [];
for (i = 0; i < 64; i++) inner[i] = 54;
for (i = 0; i < password.length; i++) inner[i] ^= password[i];
for (i = 0; i < salt.length; i++) inner[64 + i] = salt[i];
for (i = innerLen - 4; i < innerLen; i++) inner[i] = 0;
for (i = 0; i < 64; i++) outerKey[i] = 92;
for (i = 0; i < password.length; i++) outerKey[i] ^= password[i];
function incrementCounter() {
for (var i = innerLen - 1; i >= innerLen - 4; i--) {
inner[i]++;
if (inner[i] <= 255) return;
inner[i] = 0;
}
}
while (dkLen >= 32) {
incrementCounter();
dk = dk.concat(SHA256(outerKey.concat(SHA256(inner))));
dkLen -= 32;
}
if (dkLen > 0) {
incrementCounter();
dk = dk.concat(SHA256(outerKey.concat(SHA256(inner))).slice(0, dkLen));
}
return dk;
}
function salsaXOR(tmp, B, bin, bout) {
var j0 = tmp[0] ^ B[bin++], j1 = tmp[1] ^ B[bin++], j2 = tmp[2] ^ B[bin++], j3 = tmp[3] ^ B[bin++], j4 = tmp[4] ^ B[bin++], j5 = tmp[5] ^ B[bin++], j6 = tmp[6] ^ B[bin++], j7 = tmp[7] ^ B[bin++], j8 = tmp[8] ^ B[bin++], j9 = tmp[9] ^ B[bin++], j10 = tmp[10] ^ B[bin++], j11 = tmp[11] ^ B[bin++], j12 = tmp[12] ^ B[bin++], j13 = tmp[13] ^ B[bin++], j14 = tmp[14] ^ B[bin++], j15 = tmp[15] ^ B[bin++], u, i;
var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, x15 = j15;
for (i = 0; i < 8; i += 2) {
u = x0 + x12;
x4 ^= u << 7 | u >>> 32 - 7;
u = x4 + x0;
x8 ^= u << 9 | u >>> 32 - 9;
u = x8 + x4;
x12 ^= u << 13 | u >>> 32 - 13;
u = x12 + x8;
x0 ^= u << 18 | u >>> 32 - 18;
u = x5 + x1;
x9 ^= u << 7 | u >>> 32 - 7;
u = x9 + x5;
x13 ^= u << 9 | u >>> 32 - 9;
u = x13 + x9;
x1 ^= u << 13 | u >>> 32 - 13;
u = x1 + x13;
x5 ^= u << 18 | u >>> 32 - 18;
u = x10 + x6;
x14 ^= u << 7 | u >>> 32 - 7;
u = x14 + x10;
x2 ^= u << 9 | u >>> 32 - 9;
u = x2 + x14;
x6 ^= u << 13 | u >>> 32 - 13;
u = x6 + x2;
x10 ^= u << 18 | u >>> 32 - 18;
u = x15 + x11;
x3 ^= u << 7 | u >>> 32 - 7;
u = x3 + x15;
x7 ^= u << 9 | u >>> 32 - 9;
u = x7 + x3;
x11 ^= u << 13 | u >>> 32 - 13;
u = x11 + x7;
x15 ^= u << 18 | u >>> 32 - 18;
u = x0 + x3;
x1 ^= u << 7 | u >>> 32 - 7;
u = x1 + x0;
x2 ^= u << 9 | u >>> 32 - 9;
u = x2 + x1;
x3 ^= u << 13 | u >>> 32 - 13;
u = x3 + x2;
x0 ^= u << 18 | u >>> 32 - 18;
u = x5 + x4;
x6 ^= u << 7 | u >>> 32 - 7;
u = x6 + x5;
x7 ^= u << 9 | u >>> 32 - 9;
u = x7 + x6;
x4 ^= u << 13 | u >>> 32 - 13;
u = x4 + x7;
x5 ^= u << 18 | u >>> 32 - 18;
u = x10 + x9;
x11 ^= u << 7 | u >>> 32 - 7;
u = x11 + x10;
x8 ^= u << 9 | u >>> 32 - 9;
u = x8 + x11;
x9 ^= u << 13 | u >>> 32 - 13;
u = x9 + x8;
x10 ^= u << 18 | u >>> 32 - 18;
u = x15 + x14;
x12 ^= u << 7 | u >>> 32 - 7;
u = x12 + x15;
x13 ^= u << 9 | u >>> 32 - 9;
u = x13 + x12;
x14 ^= u << 13 | u >>> 32 - 13;
u = x14 + x13;
x15 ^= u << 18 | u >>> 32 - 18;
}
B[bout++] = tmp[0] = x0 + j0 | 0;
B[bout++] = tmp[1] = x1 + j1 | 0;
B[bout++] = tmp[2] = x2 + j2 | 0;
B[bout++] = tmp[3] = x3 + j3 | 0;
B[bout++] = tmp[4] = x4 + j4 | 0;
B[bout++] = tmp[5] = x5 + j5 | 0;
B[bout++] = tmp[6] = x6 + j6 | 0;
B[bout++] = tmp[7] = x7 + j7 | 0;
B[bout++] = tmp[8] = x8 + j8 | 0;
B[bout++] = tmp[9] = x9 + j9 | 0;
B[bout++] = tmp[10] = x10 + j10 | 0;
B[bout++] = tmp[11] = x11 + j11 | 0;
B[bout++] = tmp[12] = x12 + j12 | 0;
B[bout++] = tmp[13] = x13 + j13 | 0;
B[bout++] = tmp[14] = x14 + j14 | 0;
B[bout++] = tmp[15] = x15 + j15 | 0;
}
function blockCopy(dst, di, src, si, len) {
while (len--) dst[di++] = src[si++];
}
function blockXOR(dst, di, src, si, len) {
while (len--) dst[di++] ^= src[si++];
}
function blockMix(tmp, B, bin, bout, r) {
blockCopy(tmp, 0, B, bin + (2 * r - 1) * 16, 16);
for (var i = 0; i < 2 * r; i += 2) {
salsaXOR(tmp, B, bin + i * 16, bout + i * 8);
salsaXOR(tmp, B, bin + i * 16 + 16, bout + i * 8 + r * 16);
}
}
function integerify(B, bi, r) {
return B[bi + (2 * r - 1) * 16];
}
function stringToUTF8Bytes(s) {
var arr = [];
for (var i = 0; i < s.length; i++) {
var c = s.charCodeAt(i);
if (c < 128) {
arr.push(c);
} else if (c > 127 && c < 2048) {
arr.push(c >> 6 | 192);
arr.push(c & 63 | 128);
} else {
arr.push(c >> 12 | 224);
arr.push(c >> 6 & 63 | 128);
arr.push(c & 63 | 128);
}
}
return arr;
}
function bytesToHex(p) {
var enc = "0123456789abcdef".split("");
var len = p.length, arr = [], i = 0;
for (;i < len; i++) {
arr.push(enc[p[i] >>> 4 & 15]);
arr.push(enc[p[i] >>> 0 & 15]);
}
return arr.join("");
}
function bytesToBase64(p) {
var enc = ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789+/").split("");
var len = p.length, arr = [], i = 0, a, b, c, t;
while (i < len) {
a = i < len ? p[i++] : 0;
b = i < len ? p[i++] : 0;
c = i < len ? p[i++] : 0;
t = (a << 16) + (b << 8) + c;
arr.push(enc[t >>> 3 * 6 & 63]);
arr.push(enc[t >>> 2 * 6 & 63]);
arr.push(enc[t >>> 1 * 6 & 63]);
arr.push(enc[t >>> 0 * 6 & 63]);
}
if (len % 3 > 0) {
arr[arr.length - 1] = "=";
if (len % 3 === 1) arr[arr.length - 2] = "=";
}
return arr.join("");
}
var p = 1;
if (logN < 1 || logN > 31) throw new Error("scrypt: logN not be between 1 and 31");
var MAX_INT = 1 << 31 >>> 0, N = 1 << logN >>> 0, XY, V, B, tmp;
if (r * p >= 1 << 30 || r > MAX_INT / 128 / p || r > MAX_INT / 256 || N > MAX_INT / 128 / r) throw new Error("scrypt: parameters are too large");
if (typeof password === "string") password = stringToUTF8Bytes(password);
if (typeof salt === "string") salt = stringToUTF8Bytes(salt);
if (typeof Int32Array !== "undefined") {
XY = new Int32Array(64 * r);
V = new Int32Array(32 * N * r);
tmp = new Int32Array(16);
} else {
XY = [];
V = [];
tmp = new Array(16);
}
B = PBKDF2_HMAC_SHA256_OneIter(password, salt, p * 128 * r);
var xi = 0, yi = 32 * r;
function smixStart() {
for (var i = 0; i < 32 * r; i++) {
var j = i * 4;
XY[xi + i] = (B[j + 3] & 255) << 24 | (B[j + 2] & 255) << 16 | (B[j + 1] & 255) << 8 | (B[j + 0] & 255) << 0;
}
}
function smixStep1(start, end) {
for (var i = start; i < end; i += 2) {
blockCopy(V, i * (32 * r), XY, xi, 32 * r);
blockMix(tmp, XY, xi, yi, r);
blockCopy(V, (i + 1) * (32 * r), XY, yi, 32 * r);
blockMix(tmp, XY, yi, xi, r);
}
}
function smixStep2(start, end) {
for (var i = start; i < end; i += 2) {
var j = integerify(XY, xi, r) & N - 1;
blockXOR(XY, xi, V, j * (32 * r), 32 * r);
blockMix(tmp, XY, xi, yi, r);
j = integerify(XY, yi, r) & N - 1;
blockXOR(XY, yi, V, j * (32 * r), 32 * r);
blockMix(tmp, XY, yi, xi, r);
}
}
function smixFinish() {
for (var i = 0; i < 32 * r; i++) {
var j = XY[xi + i];
B[i * 4 + 0] = j >>> 0 & 255;
B[i * 4 + 1] = j >>> 8 & 255;
B[i * 4 + 2] = j >>> 16 & 255;
B[i * 4 + 3] = j >>> 24 & 255;
}
}
var nextTick = typeof setImmediate !== "undefined" ? setImmediate : setTimeout;
function interruptedFor(start, end, step, fn, donefn) {
(function performStep() {
nextTick((function() {
fn(start, start + step < end ? start + step : end);
start += step;
if (start < end) performStep(); else donefn();
}));
})();
}
function getResult(enc) {
var result = PBKDF2_HMAC_SHA256_OneIter(password, B, dkLen);
if (enc === "base64") return bytesToBase64(result); else if (enc === "hex") return bytesToHex(result); else return result;
}
if (typeof interruptStep === "function") {
encoding = callback;
callback = interruptStep;
interruptStep = 1e3;
}
if (interruptStep <= 0) {
smixStart();
smixStep1(0, N);
smixStep2(0, N);
smixFinish();
callback(getResult(encoding));
} else {
smixStart();
interruptedFor(0, N, interruptStep * 2, smixStep1, (function() {
interruptedFor(0, N, interruptStep * 2, smixStep2, (function() {
smixFinish();
callback(getResult(encoding));
}));
}));
}
}
module.exports = scrypt;
})(scryptAsync);
return scryptAsync.exports;
}
var hasRequiredCommonCredential;
function requireCommonCredential() {
if (hasRequiredCommonCredential) return commonCredential$1.exports;
hasRequiredCommonCredential = 1;
(function(module) {
(function() {
var factory = function(AppConfig = {}, Scrypt) {
var Cred = {};
Cred.setCustomize = data => {
AppConfig = data.AppConfig;
};
Cred.MINIMUM_PASSWORD_LENGTH = typeof AppConfig.minimumPasswordLength === "number" ? AppConfig.minimumPasswordLength : 8;
Cred.MINIMUM_NAME_LENGTH = 1;
Cred.MAXIMUM_NAME_LENGTH = 64;
Cred.isEmail = function(email) {
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(String(email).toLowerCase());
};
Cred.isLongEnoughPassword = function(passwd) {
return passwd.length >= Cred.MINIMUM_PASSWORD_LENGTH;
};
var isString = Cred.isString = function(x) {
return typeof x === "string";
};
Cred.isValidUsername = function(name) {
return !!(isString(name) && name.length >= Cred.MINIMUM_NAME_LENGTH);
};
Cred.isValidPassword = function(passwd) {
return !!(passwd && isString(passwd));
};
Cred.passwordsMatch = function(a, b) {
return isString(a) && isString(b) && a === b;
};
Cred.customSalt = function() {
return typeof AppConfig.loginSalt === "string" ? AppConfig.loginSalt : "";
};
Cred.deriveFromPassphrase = function(username, password, len, cb) {
Scrypt(password, username + Cred.customSalt(), 8, 1024, len || 128, 200, cb, undefined);
};
Cred.dispenser = function(bytes) {
var entropy = {
used: 0
};
var consume = function(n) {
if (entropy.used + n > bytes.length) {
throw new Error("exceeded available entropy");
}
if (typeof n !== "number") {
throw new Error("expected a number");
}
if (n <= 0) {
throw new Error("expected to consume a positive number of bytes");
}
var A;
if (bytes.slice) {
A = bytes.slice(entropy.used, entropy.used + n);
} else {
A = bytes.subarray(entropy.used, entropy.used + n);
}
entropy.used += n;
return A;
};
return consume;
};
return Cred;
};
if (module.exports) {
module.exports = factory(undefined, requireScryptAsync());
}
})();
})(commonCredential$1);
return commonCredential$1.exports;
}
var commonCredentialExports = requireCommonCredential();
var commonCredential = getDefaultExportFromCjs(commonCredentialExports);
var Credential = _mergeNamespaces({
__proto__: null,
default: commonCredential
}, [ commonCredentialExports ]);
var proxyManager$1 = {
exports: {}
};
var userObject$1 = {
exports: {}
};
var userObjectSetter = {
exports: {}
};
var commonRealtime = {
exports: {}
};
var hasRequiredCommonRealtime;
function requireCommonRealtime() {
if (hasRequiredCommonRealtime) return commonRealtime.exports;
hasRequiredCommonRealtime = 1;
(function(module) {
(() => {
const factory = () => {
var common = {};
common.whenRealtimeSyncs = function(realtime, cb) {
if (typeof realtime.getAuthDoc !== "function") {
return void console.error("improper use of this function");
}
setTimeout((function() {
if (realtime.getAuthDoc() === realtime.getUserDoc()) {
return void cb();
} else {
realtime.onSettle(cb);
}
}), 0);
};
return common;
};
if (module.exports) {
module.exports = factory();
}
})();
})(commonRealtime);
return commonRealtime.exports;
}
var hasRequiredUserObjectSetter;
function requireUserObjectSetter() {
if (hasRequiredUserObjectSetter) return userObjectSetter.exports;
hasRequiredUserObjectSetter = 1;
(function(module) {
(() => {
const factory = (Util, Hash, Realtime) => {
let window = globalThis;
var module = {};
module.setCustomize = () => {};
var clone = function(o) {
try {
return JSON.parse(JSON.stringify(o));
} catch (e) {
return undefined;
}
};
module.init = function(config, exp, files) {
var loggedIn = config.loggedIn;
var sharedFolder = config.sharedFolder;
var readOnly = config.readOnly;
var Messages = config.Messages || {};
var ROOT = exp.ROOT;
var FILES_DATA = exp.FILES_DATA;
var STATIC_DATA = exp.STATIC_DATA;
var OLD_FILES_DATA = exp.OLD_FILES_DATA;
var UNSORTED = exp.UNSORTED;
var TRASH = exp.TRASH;
var TEMPLATE = exp.TEMPLATE;
var SHARED_FOLDERS = exp.SHARED_FOLDERS;
var SHARED_FOLDERS_TEMP = exp.SHARED_FOLDERS_TEMP;
var debug = exp.debug;
exp._setReadOnly = function(state) {
readOnly = state;
if (!readOnly) {
exp.fixFiles();
}
};
exp.setHref = function(channel, id, href) {
if (!id && !channel) {
return;
}
if (readOnly) {
return;
}
var ids = id ? [ id ] : exp.findChannels([ channel ]);
ids.forEach((function(i) {
var data = exp.getFileData(i, true);
var oldHref = exp.getHref(data);
if (oldHref === href) {
return;
}
data.href = exp.cryptor.encrypt(href);
}));
};
exp.setPadAttribute = function(href, attr, value, cb) {
cb = cb || function() {};
if (readOnly) {
return void cb("EFORBIDDEN");
}
var id = exp.getIdFromHref(href);
if (!id) {
return void cb("E_INVAL_HREF");
}
if (!attr || !attr.trim()) {
return void cb("E_INVAL_ATTR");
}
var data = exp.getFileData(id, true);
if (attr === "href") {
exp.setHref(null, id, value);
} else {
data[attr] = clone(value);
}
cb(null);
};
exp.getPadAttribute = function(href, attr, cb) {
cb = cb || function() {};
var id = exp.getIdFromHref(href);
if (!id) {
return void cb(null, undefined);
}
var data = exp.getFileData(id);
cb(null, clone(data[attr]));
};
exp.pushData = function(_data, cb) {
if (typeof cb !== "function") {
cb = function() {};
}
if (readOnly) {
return void cb("EFORBIDDEN");
}
var id = Util.createRandomInteger();
var data = clone(_data);
if (data.href && data.href.indexOf("#") !== -1) {
data.href = exp.cryptor.encrypt(data.href);
}
files[FILES_DATA][id] = data;
cb(null, id);
};
exp.pushLink = function(_data, cb) {
if (typeof cb !== "function") {
cb = function() {};
}
if (readOnly) {
return void cb("EFORBIDDEN");
}
var id = Util.createRandomInteger();
var data = clone(_data);
files[STATIC_DATA][id] = data;
cb(null, id);
};
exp.pushSharedFolder = function(_data, cb) {
if (typeof cb !== "function") {
cb = function() {};
}
if (readOnly) {
return void cb("EFORBIDDEN");
}
var data = clone(_data);
var exists;
if (Object.keys(files[SHARED_FOLDERS]).some((function(k) {
if (files[SHARED_FOLDERS][k].channel === data.channel) {
if (data.href && !files[SHARED_FOLDERS][k].href) {
files[SHARED_FOLDERS][k].href = data.href;
}
exists = k;
return true;
}
}))) {
return void cb("EEXISTS", exists);
}
if (!loggedIn || config.testMode) {
return void cb("EAUTH");
}
var id = Util.createRandomInteger();
if (data.href && data.href.indexOf("#") !== -1) {
data.href = exp.cryptor.encrypt(data.href);
}
files[SHARED_FOLDERS][id] = data;
cb(null, id);
};
exp.deprecateSharedFolder = function(id, reason) {
if (readOnly) {
return;
}
var data = files[SHARED_FOLDERS][id];
if (!data) {
return;
}
var ro = !data.href || exp.cryptor.decrypt(data.href).indexOf("#") === -1;
if (!ro) {
var obj = files[SHARED_FOLDERS_TEMP][id] = JSON.parse(JSON.stringify(data));
obj.legacy = reason !== "PASSWORD_CHANGE";
}
var paths = exp.findFile(Number(id));
exp.delete(paths, null, true);
delete files[SHARED_FOLDERS][id];
};
var spliceFileData = function(id) {
if (readOnly) {
return;
}
delete files[FILES_DATA][id];
};
exp.checkDeletedFiles = function(cb) {
if (!loggedIn && !config.testMode) {
return void cb();
}
if (readOnly) {
return void cb("EFORBIDDEN");
}
var filesList = exp.getFiles([ ROOT, "hrefArray", TRASH ]);
var toClean = [];
exp.getFiles([ FILES_DATA, SHARED_FOLDERS, STATIC_DATA ]).forEach((function(id) {
if (filesList.indexOf(id) === -1) {
var fd = exp.isSharedFolder(id) ? files[SHARED_FOLDERS][id] : exp.getFileData(id);
var channelId = fd.channel;
if (fd.lastVersion) {
toClean.push(Hash.hrefToHexChannelId(fd.lastVersion));
}
if (fd.rtChannel) {
toClean.push(fd.rtChannel);
}
if (channelId) {
toClean.push(channelId);
}
if (exp.isSharedFolder(id)) {
delete files[SHARED_FOLDERS][id];
if (config.removeProxy) {
config.removeProxy(id);
}
} else if (files[STATIC_DATA][id]) {
delete files[STATIC_DATA][id];
} else {
spliceFileData(id);
}
}
}));
if (!toClean.length) {
return void cb();
}
cb(null, toClean);
};
var deleteHrefs = function(ids) {
if (readOnly) {
return;
}
ids.forEach((function(obj) {
var idx = files[obj.root].indexOf(obj.id);
files[obj.root].splice(idx, 1);
}));
};
var deleteMultipleTrashRoot = function(roots) {
if (readOnly) {
return;
}
roots.forEach((function(obj) {
var idx = files[TRASH][obj.name].indexOf(obj.el);
files[TRASH][obj.name].splice(idx, 1);
}));
};
exp.deleteMultiplePermanently = function(paths, nocheck, cb) {
if (readOnly) {
return void cb("EFORBIDDEN");
}
var allFilesPaths = paths.filter((function(x) {
return exp.isPathIn(x, [ FILES_DATA ]);
}));
if (!loggedIn && !config.testMode) {
allFilesPaths.forEach((function(path) {
var id = path[1];
if (!id) {
return;
}
spliceFileData(id);
}));
return void cb();
}
var hrefPaths = paths.filter((function(x) {
return exp.isPathIn(x, [ "hrefArray" ]);
}));
var rootPaths = paths.filter((function(x) {
return exp.isPathIn(x, [ ROOT ]);
}));
var trashPaths = paths.filter((function(x) {
return exp.isPathIn(x, [ TRASH ]);
}));
var ids = [];
hrefPaths.forEach((function(path) {
var id = exp.find(path);
ids.push({
root: path[0],
id
});
}));
deleteHrefs(ids);
rootPaths.forEach((function(path) {
var parentPath = path.slice();
var key = parentPath.pop();
var parentEl = exp.find(parentPath);
delete parentEl[key];
}));
var trashRoot = [];
trashPaths.forEach((function(path) {
var parentPath = path.slice();
var key = parentPath.pop();
var parentEl = exp.find(parentPath);
if (path.length === 4) {
trashRoot.push({
name: path[1],
el: parentEl
});
return;
}
delete parentEl[key];
}));
deleteMultipleTrashRoot(trashRoot);
if (!nocheck) {
exp.checkDeletedFiles(cb);
} else {
cb();
}
};
exp.copyFromOtherDrive = function(path, element, data, key) {
if (readOnly) {
return;
}
var toRemove = [];
Object.keys(data).forEach((function(id) {
id = Number(id);
var d = data[id];
if (d.static) {
delete d.static;
files[STATIC_DATA][id] = d;
return;
}
if (d.href) {
d.href = exp.cryptor.encrypt(d.href);
}
var found = false;
for (var i in files[FILES_DATA]) {
if (files[FILES_DATA][i].channel === d.channel) {
if (!files[FILES_DATA][i].href) {
files[FILES_DATA][i].href = d.href;
}
found = true;
break;
}
}
if (found) {
toRemove.push(id);
return;
}
files[FILES_DATA][id] = d;
}));
if (exp.isFile(element) && toRemove.indexOf(element) !== -1) {
exp.log(Messages.sharedFolders_duplicate);
return;
} else if (exp.isFolder(element)) {
var _removeExisting = function(root) {
for (var k in root) {
if (exp.isFile(root[k])) {
if (toRemove.indexOf(root[k]) !== -1) {
exp.log(Messages.sharedFolders_duplicate);
delete root[k];
}
} else if (exp.isFolder(root[k])) {
_removeExisting(root[k]);
}
}
};
_removeExisting(element);
}
var newParent = exp.find(path);
var tempName = exp.isFile(element) ? Hash.createChannelId() : key;
var newName = exp.getAvailableName(newParent, tempName);
if (Array.isArray(newParent)) {
newParent.push(element);
return;
}
newParent[newName] = element;
};
var pushToTrash = function(name, element, path) {
if (readOnly) {
return;
}
var trash = files[TRASH];
if (typeof trash[name] === "undefined") {
trash[name] = [];
}
var trashArray = trash[name];
var trashElement = {
element,
path
};
trashArray.push(trashElement);
};
exp.copyElement = function(elementPath, newParentPath) {
if (readOnly) {
return;
}
if (exp.comparePath(elementPath, newParentPath)) {
return;
}
var element = exp.find(elementPath);
var newParent = exp.find(newParentPath);
if (exp.isPathIn(newParentPath, [ TRASH ])) {
if (!elementPath || elementPath.length < 2 || elementPath[0] === TRASH) {
debug("Can't move an element from the trash to the trash: ", elementPath);
return;
}
var key = elementPath[elementPath.length - 1];
var elName = exp.isPathIn(elementPath, [ "hrefArray" ]) ? exp.getTitle(element) : key;
var parentPath = elementPath.slice();
parentPath.pop();
pushToTrash(elName, element, parentPath);
return true;
}
if (exp.isPathIn(newParentPath, [ "hrefArray" ])) {
if (exp.isFolder(element)) {
exp.log(Messages.fo_moveUnsortedError);
return;
} else {
if (elementPath[0] === newParentPath[0]) {
return;
}
var fileRoot = newParentPath[0];
if (files[fileRoot].indexOf(element) === -1) {
files[fileRoot].push(element);
}
return true;
}
}
var newName = exp.isFile(element) ? exp.getAvailableName(newParent, Hash.createChannelId()) : exp.isInTrashRoot(elementPath) ? elementPath[1] : elementPath.pop();
if (typeof newParent[newName] !== "undefined") {
exp.log(Messages.fo_unavailableName);
return;
}
newParent[newName] = element;
return true;
};
exp.forget = function(href) {
if (readOnly) {
return;
}
var id = exp.getIdFromHref(href);
if (!id) {
return;
}
if (!loggedIn && !config.testMode) {
spliceFileData(id);
return true;
}
var paths = exp.findFile(id);
exp.move(paths, [ TRASH ]);
return true;
};
exp.restoreHref = function(href) {
if (readOnly) {
return;
}
var idO = exp.getIdFromHref(href);
if (!idO || !exp.isFile(idO)) {
return;
}
var paths = exp.findFile(idO);
var allInTrash = true;
paths.forEach((function(p) {
if (p[0] === TRASH) {
exp.delete(p, null, true);
return;
}
allInTrash = false;
}));
if (allInTrash) {
exp.add(idO);
}
};
exp.add = function(id, path) {
if (readOnly) {
return;
}
if (!loggedIn && !config.testMode) {
return;
}
id = Number(id);
var data = files[FILES_DATA][id] || files[STATIC_DATA][id] || files[SHARED_FOLDERS][id];
if (!data || typeof data !== "object") {
return;
}
var newPath = path, parentEl;
if (path && !Array.isArray(path)) {
newPath = decodeURIComponent(path).split(",");
}
if (path && exp.isPathIn(newPath, [ "hrefArray" ])) {
parentEl = exp.find(newPath);
parentEl.push(id);
return;
}
var filesList = exp.getFiles([ ROOT, TRASH, "hrefArray" ]);
if (filesList.indexOf(id) === -1 && !newPath) {
newPath = [ ROOT ];
}
if (path && exp.isPathIn(newPath, [ ROOT ])) {
parentEl = exp.find(newPath);
if (parentEl) {
var newName = exp.getAvailableName(parentEl, Hash.createChannelId());
parentEl[newName] = id;
return;
} else {
parentEl = exp.find([ ROOT ]);
newPath.slice(1).forEach((function(folderName) {
parentEl = parentEl[folderName] = parentEl[folderName] || {};
}));
parentEl[Hash.createChannelId()] = id;
}
}
};
exp.setFolderData = function(path, key, value, cb) {
if (readOnly) {
return;
}
var folder = exp.find(path);
if (!exp.isFolder(folder) || exp.isSharedFolder(folder)) {
return;
}
if (!exp.hasFolderData(folder)) {
var hashKey = "000" + Hash.createChannelId().slice(0, -3);
folder[hashKey] = {
metadata: true
};
}
exp.getFolderData(folder)[key] = value;
cb();
};
var onSync = function(next) {
if (exp.rt) {
exp.rt.sync();
Realtime.whenRealtimeSyncs(exp.rt, next);
} else {
window.setTimeout(next, 1e3);
}
};
exp.migrateReadOnly = function(cb) {
if (readOnly || !config.editKey) {
return void cb({
error: "EFORBIDDEN"
});
}
if (files.version >= 2) {
return void cb();
}
files.migrateRo = 1;
var next = function() {
var copy = JSON.parse(JSON.stringify(files));
exp.reencrypt(config.editKey, config.editKey, copy);
setTimeout((function() {
if (files.version >= 2) {
return void cb();
}
Object.keys(copy).forEach((function(k) {
files[k] = copy[k];
}));
files.version = 2;
delete files.migrateRo;
onSync(cb);
}), 1e3);
};
onSync(next);
};
exp.migrate = function(cb) {
if (readOnly) {
return void cb();
}
var fixUnsorted = function() {
if (!files[UNSORTED] || !files[OLD_FILES_DATA]) {
return;
}
debug("UNSORTED still exists in the object, removing it...");
var us = files[UNSORTED];
if (us.length === 0) {
delete files[UNSORTED];
return;
}
us.forEach((function(el) {
if (typeof el !== "string") {
return;
}
var data = files[OLD_FILES_DATA].filter((function(x) {
return x.href === el;
}));
if (data.length === 0) {
files[OLD_FILES_DATA].push({
href: el
});
}
return;
}));
delete files[UNSORTED];
};
var migrateToNewFormat = function(todo) {
if (!files[OLD_FILES_DATA]) {
return void todo();
}
try {
debug("Migrating file system...");
files.migrate = 1;
var next = function() {
var oldData = files[OLD_FILES_DATA].slice();
if (!files[FILES_DATA]) {
files[FILES_DATA] = {};
}
var newData = files[FILES_DATA];
oldData.forEach((function(obj) {
if (!obj || !obj.href) {
return;
}
var href = obj.href;
var id = Util.createRandomInteger();
var paths = exp.findFile(href);
var data = obj;
var key = Hash.createChannelId();
if (data) {
newData[id] = data;
} else {
newData[id] = {
href
};
}
paths.forEach((function(p) {
var parentPath = p.slice();
var okey = parentPath.pop();
var parent = exp.find(parentPath);
if (exp.isInTrashRoot(p)) {
parent.element = id;
newData[id].filename = p[1];
return;
}
if (exp.isPathIn(p, [ "hrefArray" ])) {
parent[okey] = id;
return;
}
parent[key] = id;
newData[id].filename = okey;
delete parent[okey];
}));
}));
delete files[OLD_FILES_DATA];
delete files.migrate;
todo();
};
onSync(next);
} catch (e) {
console.error(e);
todo();
}
};
fixUnsorted();
migrateToNewFormat(cb);
};
exp.fixFiles = function(silent) {
if (readOnly) {
return;
}
if (silent) {
debug = function() {};
}
var t0 = +new Date;
debug("Cleaning file system...");
var before = JSON.stringify(files);
var fixRoot = function(elem) {
if (typeof files[ROOT] !== "object") {
debug("ROOT was not an object");
files[ROOT] = {};
}
var element = elem || files[ROOT];
if (!element) {
return console.error("Invalid element in root");
}
var nbMetadataFolders = 0;
var static_data = files[STATIC_DATA];
var files_data = files[FILES_DATA];
var element_el;
for (var el in element) {
element_el = element[el];
if (element_el === null) {
console.error("element[%s] is null", el);
delete element[el];
continue;
}
if (exp.isFolderData(element_el)) {
if (nbMetadataFolders !== 0) {
debug("Multiple metadata files in folder");
delete element[el];
}
nbMetadataFolders++;
continue;
}
if (!exp.isFile(element_el, true) && !exp.isFolder(element_el)) {
debug("An element in ROOT was not a folder nor a file. ", element_el);
delete element[el];
continue;
}
if (exp.isFolder(element_el)) {
fixRoot(element_el);
continue;
}
if (typeof element_el === "string") {
var id = Util.createRandomInteger();
var key = Hash.createChannelId();
files_data[id] = {
href: exp.cryptor.encrypt(element_el),
filename: el
};
element[key] = id;
delete element[el];
}
if (typeof element_el === "number") {
var data = files_data[element_el] || static_data[element_el];
if (!data) {
debug("An element in ROOT doesn't have associated data", element_el, el);
delete element[el];
}
}
}
};
var fixTrashRoot = function() {
if (sharedFolder) {
return;
}
if (typeof files[TRASH] !== "object") {
debug("TRASH was not an object");
files[TRASH] = {};
}
var tr = files[TRASH];
var toClean;
var addToClean = function(obj, idx, el) {
if (typeof obj !== "object") {
toClean.push(idx);
return;
}
if (exp.isSharedFolder(obj.element)) {
return;
}
if (!exp.isFile(obj.element, true) && !exp.isFolder(obj.element)) {
toClean.push(idx);
return;
}
if (!Array.isArray(obj.path)) {
toClean.push(idx);
return;
}
if (typeof obj.element === "string") {
var id = Util.createRandomInteger();
files[FILES_DATA][id] = {
href: exp.cryptor.encrypt(obj.element),
filename: el
};
obj.element = id;
}
if (exp.isFolder(obj.element)) {
fixRoot(obj.element);
}
if (typeof obj.element === "number") {
var data = files[FILES_DATA][obj.element] || files[STATIC_DATA][obj.element];
if (!data) {
debug("An element in TRASH doesn't have associated data", obj.element, el);
toClean.push(idx);
}
}
};
for (var el in tr) {
if (!Array.isArray(tr[el])) {
debug("An element in TRASH root is not an array. ", tr[el]);
delete tr[el];
} else if (tr[el].length === 0) {
debug("Empty array in TRASH root. ", tr[el]);
delete tr[el];
} else {
toClean = [];
for (var j = 0; j < tr[el].length; j++) {
addToClean(tr[el][j], j, el);
}
for (var i = toClean.length - 1; i >= 0; i--) {
tr[el].splice(toClean[i], 1);
}
}
}
};
var fixTemplate = function() {
if (sharedFolder) {
return;
}
if (!Array.isArray(files[TEMPLATE])) {
debug("TEMPLATE was not an array");
files[TEMPLATE] = [];
}
var dedup = Util.deduplicateString(files[TEMPLATE]);
if (dedup.length !== files[TEMPLATE].length) {
files[TEMPLATE] = dedup;
}
var us = files[TEMPLATE];
var rootFiles = exp.getFiles([ ROOT ]);
var toClean = [];
us.forEach((function(el, idx) {
if (!exp.isFile(el, true) || rootFiles.indexOf(el) !== -1) {
toClean.push(el);
return;
}
if (typeof el === "string") {
var id = Util.createRandomInteger();
files[FILES_DATA][id] = {
href: exp.cryptor.encrypt(el)
};
us[idx] = id;
return;
}
if (typeof el === "number") {
var data = files[FILES_DATA][el];
if (!data) {
debug("An element in TEMPLATE doesn't have associated data", el);
toClean.push(el);
}
}
}));
toClean.forEach((function(el) {
var idx = us.indexOf(el);
if (idx !== -1) {
us.splice(idx, 1);
}
}));
};
var fixFilesData = function() {
if (typeof files[FILES_DATA] !== "object") {
debug("FILES_DATA was not an object");
files[FILES_DATA] = {};
}
var fd = files[FILES_DATA];
var rootFiles = exp.getFiles([ ROOT, TRASH, "hrefArray" ]);
var root = exp.find([ ROOT ]);
var toClean = [];
for (var id in fd) {
if (String(id) !== String(Number(id))) {
debug("Invalid file ID in filesData.", id);
toClean.push(id);
continue;
}
id = Number(id);
var el = fd[id];
if (!el || typeof el !== "object") {
debug("An element in filesData was not an object.", el);
toClean.push(id);
continue;
}
if (!el.href && !el.roHref) {
debug("Removing an element in filesData with a missing href.", el);
toClean.push(id);
continue;
}
var decryptedHref;
try {
decryptedHref = el.href && (el.href.indexOf("#") !== -1 ? el.href : exp.cryptor.decrypt(el.href));
} catch (e) {}
if (decryptedHref && decryptedHref.indexOf("#") === -1) {
continue;
}
var parsed = Hash.parsePadUrl(decryptedHref || el.roHref);
var secret;
if (!parsed.hash) {
debug("Removing an element in filesData with a invalid href.", el);
toClean.push(id);
continue;
}
if (!parsed.type) {
debug("Removing an element in filesData with a invalid type.", el);
toClean.push(id);
continue;
}
if (decryptedHref && parsed.hashData.type === "pad" && parsed.hashData.version) {
if (parsed.hashData.mode === "view") {
el.roHref = decryptedHref;
delete el.href;
} else if (!el.roHref) {
secret = Hash.getSecrets(parsed.type, parsed.hash, el.password);
el.roHref = "/" + parsed.type + "/#" + Hash.getViewHashFromKeys(secret);
} else {
var parsed2 = Hash.parsePadUrl(el.roHref);
if (!parsed2.hash || !parsed2.type) {
secret = Hash.getSecrets(parsed.type, parsed.hash, el.password);
el.roHref = "/" + parsed.type + "/#" + Hash.getViewHashFromKeys(secret);
}
}
}
if (parsed.hashData.version === 0) {
delete el.roHref;
}
if (decryptedHref && decryptedHref.slice(0, 1) !== "/") {
el.href = exp.cryptor.encrypt(Hash.getRelativeHref(decryptedHref));
}
if (!el.ctime) {
el.ctime = el.atime;
}
if (!el.title) {
el.title = exp.getDefaultName(parsed);
}
if (!el.channel) {
try {
if (!secret) {
secret = Hash.getSecrets(parsed.type, parsed.hash, el.password);
}
el.channel = secret.channel;
console.log(el);
debug("Adding missing channel in filesData ", el.channel);
} catch (e) {
console.error(e);
}
}
if (!Hash.isValidChannel(el.channel)) {
console.error("Remove invalid channel", el.channel, el);
}
if ((loggedIn || config.testMode) && rootFiles.indexOf(id) === -1) {
debug("An element in filesData was not in ROOT, TEMPLATE or TRASH.", id, el);
var newName = Hash.createChannelId();
root[newName] = id;
continue;
}
}
toClean.forEach((function(id) {
spliceFileData(id);
}));
var sd = files[STATIC_DATA];
var toCleanSD = [];
for (var id2 in sd) {
id2 = Number(id2);
var el2 = sd[id2];
if (!el2 || typeof el2 !== "object" || !el2.href) {
toCleanSD.push(id2);
continue;
}
if ((loggedIn || config.testMode) && rootFiles.indexOf(id2) === -1) {
toCleanSD.push(id2);
continue;
}
}
var spliceSD = function(id) {
if (readOnly) {
return;
}
delete files[STATIC_DATA][id];
};
toCleanSD.forEach(spliceSD);
};
var fixSharedFolders = function() {
if (sharedFolder) {
return;
}
if (typeof files[SHARED_FOLDERS] !== "object") {
debug("SHARED_FOLDER was not an object");
files[SHARED_FOLDERS] = {};
}
var sf = files[SHARED_FOLDERS];
var rootFiles = exp.getFiles([ ROOT, TRASH ]);
var root = exp.find([ ROOT ]);
var parsed, el;
for (var id in sf) {
el = sf[id];
id = Number(id);
var href;
try {
href = el.href && (el.href.indexOf("#") !== -1 ? el.href : exp.cryptor.decrypt(el.href));
} catch (e) {}
parsed = Hash.parsePadUrl(href || el.roHref);
if (!parsed || !parsed.hash || parsed.hash === "undefined") {
delete sf[id];
continue;
}
if (rootFiles.indexOf(id) === -1) {
console.log("missing" + id);
var newName = Hash.createChannelId();
root[newName] = id;
}
}
};
var fixSharedFoldersTemp = function() {
if (sharedFolder) {
return;
}
if (typeof files[SHARED_FOLDERS_TEMP] !== "object") {
debug("SHARED_FOLDER_TEMP was not an object");
files[SHARED_FOLDERS_TEMP] = {};
}
var sft = files[SHARED_FOLDERS_TEMP];
var sf = files[SHARED_FOLDERS];
for (var id in sft) {
if (sf[id]) {
delete sft[id];
}
}
};
var fixStaticData = function() {
if (!Util.isObject(files[STATIC_DATA])) {
debug("STATIC_DATA was not an object");
files[STATIC_DATA] = {};
}
};
var fixDrive = function() {
Object.keys(files).forEach((function(key) {
if (key.slice(0, 1) === "/") {
delete files[key];
}
}));
};
fixStaticData();
fixRoot();
fixTrashRoot();
fixTemplate();
fixFilesData();
fixDrive();
fixSharedFolders();
fixSharedFoldersTemp();
var ms = +new Date - t0 + "ms";
if (JSON.stringify(files) !== before) {
debug("Your file system was corrupted. It has been cleaned so that the pads you visit can be stored safely.", ms);
return;
}
debug("File system was clean.", ms);
};
return exp;
};
return module;
};
if (module.exports) {
module.exports = factory(requireCommonUtil(), requireCommonHash(), requireCommonRealtime());
}
})();
})(userObjectSetter);
return userObjectSetter.exports;
}
var hasRequiredUserObject;
function requireUserObject() {
if (hasRequiredUserObject) return userObject$1.exports;
hasRequiredUserObject = 1;
(function(module) {
(() => {
const factory = (Util, Hash, Constants, UOSetter, Crypto, Messages = {}) => {
let window = globalThis;
var module = {};
module.setCustomize = data => {
Messages = data.Messages;
UOSetter.setCustomize(data);
};
var ROOT = module.ROOT = "root";
var UNSORTED = module.UNSORTED = "unsorted";
var TRASH = module.TRASH = "trash";
var TEMPLATE = module.TEMPLATE = "template";
var SHARED_FOLDERS = module.SHARED_FOLDERS = "sharedFolders";
var SHARED_FOLDERS_TEMP = module.SHARED_FOLDERS_TEMP = "sharedFoldersTemp";
var FILES_DATA = module.FILES_DATA = Constants.storageKey;
var OLD_FILES_DATA = module.OLD_FILES_DATA = Constants.oldStorageKey;
var STATIC_DATA = module.STATIC_DATA = "static";
var getLocaleDate = function() {
if (window.Intl && window.Intl.DateTimeFormat) {
var options = {
weekday: "short",
year: "numeric",
month: "long",
day: "numeric"
};
return new window.Intl.DateTimeFormat(undefined, options).format(new Date);
}
return (new Date).toString().split(" ").slice(0, 4).join(" ");
};
module.getDefaultName = function(parsed) {
var type = parsed.type;
var name = Messages.type[type] + " - " + getLocaleDate();
return name;
};
var createCryptor = module.createCryptor = function(key) {
var cryptor = {};
if (!key) {
cryptor.encrypt = function(x) {
return x;
};
cryptor.decrypt = function(x) {
return x;
};
return cryptor;
}
try {
var c = Crypto.createEncryptor(key);
cryptor.encrypt = function(href) {
try {
if (href.slice(0, 7) === "/file/#") {
return href;
}
return c.encrypt(href);
} catch (e) {
return;
}
};
cryptor.decrypt = function(msg) {
try {
return c.decrypt(msg);
} catch (e) {
return;
}
};
} catch (e) {
console.error(e);
}
return cryptor;
};
module.getHref = function(pad, cryptor) {
if (pad.href && pad.href.indexOf("#") !== -1) {
return pad.href;
}
if (pad.href && cryptor) {
var d = cryptor.decrypt(pad.href);
if (d && d.indexOf("#") !== -1) {
return d;
}
}
return pad.roHref;
};
module.reencrypt = function(oldKey, newKey, obj) {
if (!obj) {
return void console.error("Nothing to reencrypt");
}
var oldCryptor = createCryptor(oldKey);
var newCryptor = createCryptor(newKey);
Object.keys(obj[FILES_DATA]).forEach((function(id) {
var data = obj[FILES_DATA][id] || {};
if (data.href && data.roHref && !data.fileType) {
var _href = data.href && data.href.indexOf("#") === -1 ? oldCryptor.decrypt(data.href) : data.href;
if (!_href) {
return;
}
data.href = newCryptor.encrypt(_href);
}
}));
Object.keys(obj[SHARED_FOLDERS] || {}).forEach((function(id) {
var data = obj[SHARED_FOLDERS][id] || {};
if (data.href) {
var _href = data.href && data.href.indexOf("#") === -1 ? oldCryptor.decrypt(data.href) : data.href;
if (!_href) {
return;
}
data.href = newCryptor.encrypt(_href);
}
}));
Object.keys(obj[SHARED_FOLDERS_TEMP] || {}).forEach((function(id) {
var data = obj[SHARED_FOLDERS_TEMP][id] || {};
if (data.href) {
var _href = data.href && data.href.indexOf("#") === -1 ? oldCryptor.decrypt(data.href) : data.href;
if (!_href) {
return;
}
data.href = newCryptor.encrypt(_href);
}
}));
};
module.init = function(files, config) {
var exp = {};
exp.cryptor = createCryptor(config.editKey);
exp.setReadOnly = function(state, key) {
config.editKey = key;
exp.cryptor = createCryptor(key);
exp.cryptor.k = Math.random();
exp.readOnly = state;
if (exp._setReadOnly) {
exp._setReadOnly(state);
}
};
exp.readOnly = config.readOnly;
exp.reencrypt = module.reencrypt;
exp.getDefaultName = module.getDefaultName;
var sframeChan = config.sframeChan;
var NEW_FOLDER_NAME = Messages.fm_newFolder || "New folder";
var NEW_FILE_NAME = Messages.fm_newFile || "New file";
exp.ROOT = ROOT;
exp.STATIC_DATA = STATIC_DATA;
exp.UNSORTED = UNSORTED;
exp.TRASH = TRASH;
exp.TEMPLATE = TEMPLATE;
exp.SHARED_FOLDERS = SHARED_FOLDERS;
exp.SHARED_FOLDERS_TEMP = SHARED_FOLDERS_TEMP;
exp.FILES_DATA = FILES_DATA;
exp.OLD_FILES_DATA = OLD_FILES_DATA;
var sharedFolder = exp.sharedFolder = config.sharedFolder;
exp.id = config.id;
var logging = function() {
console.debug.apply(console, arguments);
};
var log = exp.log = config.log || logging;
var logError = config.logError || logging;
var debug = exp.debug = config.debug || logging;
exp.fixFiles = function() {};
var error = exp.error = function() {
if (sframeChan) {
return void sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "fixFiles",
data: {}
}, (function() {}));
} else if (typeof exp.fixFiles === "function") {
exp.fixFiles();
}
console.error.apply(console, arguments);
exp.fixFiles();
};
if (config.outer) {
UOSetter.init(config, exp, files);
}
exp.getStructure = function() {
var a = {};
a[ROOT] = {};
a[TRASH] = {};
a[FILES_DATA] = {};
a[TEMPLATE] = [];
a[SHARED_FOLDERS] = {};
return a;
};
var getHref = exp.getHref = function(pad) {
return module.getHref(pad, exp.cryptor);
};
var type = function(dat) {
return dat === null ? "null" : Array.isArray(dat) ? "array" : typeof dat;
};
exp.isValidDrive = function(obj) {
var base = exp.getStructure();
return typeof obj === "object" && Object.keys(base).every((function(key) {
return obj[key] && type(base[key]) === type(obj[key]);
}));
};
var getHrefArray = function() {
return [ TEMPLATE ];
};
var compareFiles = function(fileA, fileB) {
return fileA === fileB;
};
var isSharedFolder = exp.isSharedFolder = function(element) {
if (sharedFolder) {
return false;
}
return Boolean(files[SHARED_FOLDERS] && files[SHARED_FOLDERS][element]);
};
var isFile = exp.isFile = function(element, allowStr) {
if (isSharedFolder(element)) {
return false;
}
return typeof element === "number" || (typeof files[OLD_FILES_DATA] !== "undefined" || allowStr) && typeof element === "string";
};
var isFolderData = exp.isFolderData = function(element) {
return typeof element === "object" && element.metadata === true;
};
exp.isReadOnlyFile = function(element) {
if (!isFile(element)) {
return false;
}
var data = exp.getFileData(element);
if (!data.roHref) {
return;
}
return Boolean(data.roHref && !data.href);
};
exp.isStaticFile = function(element) {
return Boolean(files[STATIC_DATA] && files[STATIC_DATA][element]);
};
var isFolder = exp.isFolder = function(element) {
if (isFolderData(element)) {
return false;
}
return typeof element === "object" && !element.channel || isSharedFolder(element);
};
exp.isFolderEmpty = function(element) {
if (!isFolder(element)) {
return false;
}
if (Object.keys(element).length === 0) {
return true;
}
if (Object.keys(element).length === 1 && isFolderData(element[Object.keys(element)[0]])) {
return true;
}
return false;
};
exp.hasSubfolder = function(element, trashRoot) {
if (!isFolder(element)) {
return false;
}
var subfolder = 0;
var addSubfolder = function(el) {
subfolder += isFolder(el.element) ? 1 : 0;
};
for (var f in element) {
if (trashRoot) {
if (Array.isArray(element[f])) {
element[f].forEach(addSubfolder);
}
} else {
subfolder += isFolder(element[f]) ? 1 : 0;
}
}
return subfolder;
};
exp.hasFile = function(element, trashRoot) {
if (!isFolder(element)) {
return false;
}
var file = 0;
var addFile = function(el) {
file += isFile(el.element) ? 1 : 0;
};
for (var f in element) {
if (trashRoot) {
if (Array.isArray(element[f])) {
element[f].forEach(addFile);
}
} else {
file += isFile(element[f]) ? 1 : 0;
}
}
return file;
};
exp.hasFolderData = function(folder) {
for (var el in folder) {
if (isFolderData(folder[el])) {
return true;
}
}
};
var hasSubSharedFolder = exp.hasSubSharedFolder = function(folder) {
for (var el in folder) {
if (isSharedFolder(folder[el])) {
return true;
} else if (isFolder(folder[el])) {
if (hasSubSharedFolder(folder[el])) {
return true;
}
}
}
return false;
};
var getFileData = exp.getFileData = function(file, editable) {
if (!file) {
return;
}
var link;
try {
link = (files[STATIC_DATA] || {})[file];
} catch (err) {
console.error(err);
}
if (link) {
var _link = editable ? link : Util.clone(link);
if (!editable) {
_link.static = true;
}
return _link;
}
var data;
try {
data = files[FILES_DATA][file] || {};
} catch (err) {
console.error(err);
data = {};
}
if (!editable) {
data = JSON.parse(JSON.stringify(data));
if (data.href && data.href.indexOf("#") === -1) {
if (config.editKey) {
try {
data.href = exp.cryptor.decrypt(data.href);
} catch (e) {
delete data.href;
}
} else {
delete data.href;
}
}
}
return data;
};
exp.getFolderData = function(folder) {
for (var el in folder) {
if (isFolderData(folder[el])) {
return folder[el];
}
}
return {};
};
var getTitle = exp.getTitle = function(file, type) {
if (isSharedFolder(file)) {
return "??";
}
var data = getFileData(file);
if (!data) {
error("unable to retrieve data about the requested file: ", file, data);
return;
}
if (data.static) {
return data.name;
}
if (!file || !(data.href || data.roHref)) {
error("getTitle called with a non-existing file id: ", file, data);
return;
}
if (type === "title") {
return data.title;
}
if (type === "name") {
return data.filename;
}
return data.filename || data.title || NEW_FILE_NAME;
};
var comparePath = exp.comparePath = function(a, b) {
if (!a || !b || !Array.isArray(a) || !Array.isArray(b)) {
return false;
}
if (a.length !== b.length) {
return false;
}
var result = true;
var i = a.length - 1;
while (result && i >= 0) {
result = a[i] === b[i];
i--;
}
return result;
};
var isSubpath = exp.isSubpath = function(path, parentPath) {
var pathA = parentPath.slice();
var pathB = path.slice(0, pathA.length);
return comparePath(pathA, pathB);
};
var isPathIn = exp.isPathIn = function(path, categories) {
if (!categories) {
return;
}
var idx = categories.indexOf("hrefArray");
if (idx !== -1) {
categories.splice(idx, 1);
categories = categories.concat(getHrefArray());
}
return categories.some((function(c) {
return Array.isArray(path) && path[0] === c;
}));
};
var isInTrashRoot = exp.isInTrashRoot = function(path) {
return path[0] === TRASH && path.length === 4;
};
var findElement = function(root, pathInput) {
if (!pathInput) {
error("Invalid path:\n", pathInput, "\nin root\n", root);
return;
}
if (pathInput.length === 0) {
return root;
}
var path = pathInput.slice();
var key = path.shift();
if (typeof root[key] === "undefined") {
debug("Unable to find the key '" + key + "' in the root object provided:", root);
return;
}
return findElement(root[key], path);
};
var find = exp.find = function(path) {
return findElement(files, path);
};
var getFilesRecursively = exp.getFilesRecursively = function(root, arr) {
arr = arr || [];
for (var e in root) {
if (isFile(root[e]) || isSharedFolder(root[e])) {
if (arr.indexOf(root[e]) === -1) {
arr.push(root[e]);
}
} else if (!isFolderData(root[e])) {
getFilesRecursively(root[e], arr);
}
}
return arr;
};
var _getFiles = {};
_getFiles["array"] = function(cat) {
if (!files[cat]) {
files[cat] = [];
}
return files[cat].slice();
};
getHrefArray().forEach((function(c) {
_getFiles[c] = function() {
return _getFiles["array"](c);
};
}));
_getFiles["hrefArray"] = function() {
var ret = [];
if (sharedFolder) {
return ret;
}
getHrefArray().forEach((function(c) {
ret = ret.concat(_getFiles[c]());
}));
return Util.deduplicateString(ret);
};
_getFiles[ROOT] = function() {
var ret = [];
getFilesRecursively(files[ROOT], ret);
return ret;
};
_getFiles[TRASH] = function() {
var root = files[TRASH];
var ret = [];
var addFiles = function(el) {
if (isFile(el.element) || isSharedFolder(el.element)) {
if (ret.indexOf(el.element) === -1) {
ret.push(el.element);
}
} else {
getFilesRecursively(el.element, ret);
}
};
for (var e in root) {
if (!Array.isArray(root[e])) {
error("Trash contains a non-array element");
return;
}
root[e].forEach(addFiles);
}
return ret;
};
_getFiles[OLD_FILES_DATA] = function() {
var ret = [];
if (!files[OLD_FILES_DATA]) {
return ret;
}
files[OLD_FILES_DATA].forEach((function(el) {
if (el.href && ret.indexOf(el.href) === -1) {
ret.push(el.href);
}
}));
return ret;
};
_getFiles[STATIC_DATA] = function() {
var ret = [];
if (!files[STATIC_DATA]) {
return ret;
}
return Object.keys(files[STATIC_DATA]).map(Number).filter(Boolean);
};
_getFiles[FILES_DATA] = function() {
var ret = [];
if (!files[FILES_DATA]) {
return ret;
}
return Object.keys(files[FILES_DATA]).map(Number).filter(Boolean);
};
_getFiles[SHARED_FOLDERS] = function() {
var ret = [];
if (!files[SHARED_FOLDERS]) {
return ret;
}
return Object.keys(files[SHARED_FOLDERS]).map(Number).filter(Boolean);
};
var getFiles = exp.getFiles = function(categories) {
var ret = [];
if (!categories || !categories.length) {
categories = [ ROOT, "hrefArray", TRASH, OLD_FILES_DATA, FILES_DATA, SHARED_FOLDERS ];
}
categories.forEach((function(c) {
if (typeof _getFiles[c] === "function") {
ret = ret.concat(_getFiles[c]());
}
}));
return Util.deduplicateString(ret);
};
var getIdFromHref = exp.getIdFromHref = function(_href) {
var result;
var noPassword = function(str) {
if (!str) {
return;
}
var parsed = Hash.parsePadUrl(str);
return parsed.getUrl().replace(/\/p\/?/, "/");
};
var href = noPassword(_href);
getFiles([ FILES_DATA ]).some((function(id) {
if (noPassword(getHref(files[FILES_DATA][id])) === href || noPassword(files[FILES_DATA][id].roHref) === href) {
result = id;
return true;
}
}));
return result;
};
exp.getSFIdFromHref = function(_href) {
var result;
var noPassword = function(str) {
if (!str) {
return;
}
var parsed = Hash.parsePadUrl(str);
return parsed.getUrl().replace(/\/p\/?/, "/");
};
var href = noPassword(_href);
getFiles([ SHARED_FOLDERS ]).some((function(id) {
if (noPassword(getHref(files[SHARED_FOLDERS][id])) === href || noPassword(files[SHARED_FOLDERS][id].roHref) === href) {
result = id;
return true;
}
}));
return result;
};
var _findFileInRoot = function(path, files) {
if (!isPathIn(path, [ ROOT, TRASH ])) {
return [];
}
files = Array.isArray(files) ? files : [ files ];
var paths = {};
var root = find(path);
var addPaths = function(p) {
Object.keys(p).forEach((file => {
paths[file] ||= [];
Array.prototype.push.apply(paths[file], p[file]);
}));
};
if (isFile(root) || isSharedFolder(root)) {
files.some((file => {
if (compareFiles(file, root)) {
paths[file] ||= [];
paths[file].push(path);
}
}));
return paths;
}
if (isFolder(root)) {
for (var e in root) {
let nPath = path.slice();
nPath.push(e);
addPaths(_findFileInRoot(nPath, files));
}
}
return paths;
};
var _findFileInHrefArray = function(rootName, toFind) {
if (sharedFolder) {
return {};
}
if (!files[rootName]) {
return {};
}
var unsorted = files[rootName].slice();
var ret = {};
var i = -1;
toFind.forEach((file => {
while ((i = unsorted.indexOf(file, i + 1)) !== -1) {
ret[file] ||= [];
ret[file].push([ rootName, i ]);
}
}));
return ret;
};
var _findFileInTrash = function(path, files) {
if (sharedFolder) {
return [];
}
var root = find(path);
var paths = {};
var addPaths = function(p) {
Object.keys(p).forEach((file => {
paths[file] ||= [];
Array.prototype.push.apply(paths[file], p[file]);
}));
};
if (path.length === 1 && typeof root === "object") {
Object.keys(root).forEach((function(key) {
var arr = root[key];
if (!Array.isArray(arr)) {
return;
}
var nPath = path.slice();
nPath.push(key);
addPaths(_findFileInTrash(nPath, files));
}));
}
if (path.length === 2) {
if (!Array.isArray(root)) {
return [];
}
root.forEach((function(el, i) {
var nPath = path.slice();
nPath.push(i);
nPath.push("element");
if (isFile(el.element)) {
files.some((file => {
if (compareFiles(file, el.element)) {
paths[file] ||= [];
paths[file].push(nPath);
}
}));
return;
}
addPaths(_findFileInTrash(nPath, files));
}));
}
if (path.length >= 4) {
addPaths(_findFileInRoot(path, files));
}
return paths;
};
var findFiles = exp.findFiles = function(files) {
var rootpaths = _findFileInRoot([ ROOT ], files);
var templatepaths = _findFileInHrefArray(TEMPLATE, files);
var trashpaths = _findFileInTrash([ TRASH ], files);
let res = {};
files.forEach((file => {
res[file] = [];
}));
[ rootpaths, templatepaths, trashpaths ].forEach((r => {
Object.keys(r).forEach((file => {
res[file] ||= [];
Array.prototype.push.apply(res[file], r[file]);
}));
}));
return res;
};
var findFile = exp.findFile = function(file) {
let res = findFiles([ file ]);
return res[file] || [];
};
exp.findChannels = function(channels, includeSharedFolders) {
var allFilesList = files[FILES_DATA];
var sfList = files[SHARED_FOLDERS];
var paths = [ FILES_DATA ];
if (includeSharedFolders) {
paths.push(SHARED_FOLDERS);
}
return getFiles(paths).filter((function(k) {
var data = allFilesList[k] || sfList[k] || {};
return channels.indexOf(data.channel) !== -1;
}));
};
exp.search = function(value) {
if (typeof value !== "string") {
return [];
}
value = value.trim();
var res = [];
var allFilesList = files[FILES_DATA];
var allSFList = files[SHARED_FOLDERS];
var lValue = value.toLowerCase();
var tags;
if (/^#/.test(lValue)) {
tags = [ lValue.slice(1).trim() ];
}
var containsSearchedTag = function(T) {
if (!tags) {
return false;
}
if (!T.length) {
return false;
}
T = T.map((function(t) {
return t.toLowerCase();
}));
return tags.some((function(tag) {
return T.some((function(t) {
return t === tag;
}));
}));
};
getFiles([ FILES_DATA, SHARED_FOLDERS ]).forEach((function(id) {
var data = allFilesList[id] || allSFList[id];
if (!data) {
return;
}
if (Array.isArray(data.tags) && containsSearchedTag(data.tags)) {
return void res.push(id);
}
var title = data.title || data.lastTitle;
if (title && title.toLowerCase().indexOf(lValue) !== -1 || data.filename && data.filename.toLowerCase().indexOf(lValue) !== -1) {
res.push(id);
}
}));
var href = Hash.getRelativeHref(value);
if (href) {
var id = getIdFromHref(href);
if (id) {
res.push(id);
}
}
res = Util.deduplicateString(res);
var ret = [];
res.forEach((function(l) {
ret.push({
id: l,
paths: findFile(l),
data: exp.getFileData(l)
});
}));
var resFolders = [];
var findFoldersRec = function(folder, path) {
for (var key in folder) {
if (isFolder(folder[key]) && !isSharedFolder(folder[key])) {
if (key.toLowerCase().indexOf(lValue) !== -1) {
resFolders.push({
id: null,
paths: [ path.concat(key) ],
data: {
title: key
}
});
}
findFoldersRec(folder[key], path.concat(key));
}
}
};
findFoldersRec(files[ROOT], [ ROOT ]);
resFolders = resFolders.sort((function(a, b) {
return a.data.title.toLowerCase() > b.data.title.toLowerCase();
}));
ret = resFolders.concat(ret);
return ret;
};
exp.getRecentPads = function() {
var allFiles = files[FILES_DATA];
var sorted = Object.keys(allFiles).filter((function(a) {
return allFiles[a];
})).sort((function(a, b) {
return allFiles[b].atime - allFiles[a].atime;
})).map((function(str) {
return Number(str);
}));
return sorted;
};
exp.getOwnedPads = function(edPub) {
var allFiles = files[FILES_DATA];
return Object.keys(allFiles).filter((function(id) {
return allFiles[id].owners && allFiles[id].owners.indexOf(edPub) !== -1;
})).map((function(k) {
return Number(k);
}));
};
var getAvailableName = exp.getAvailableName = function(parentEl, name) {
if (typeof parentEl[name] === "undefined") {
return name;
}
var newName = name;
var i = 1;
while (typeof parentEl[newName] !== "undefined") {
newName = name + "_" + i;
i++;
}
return newName;
};
var move = exp.move = function(paths, newPath, cb) {
if (sframeChan) {
return void sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "move",
data: {
paths,
newPath
}
}, cb);
}
var toRemove = [];
paths.forEach((function(p) {
var parentPath = p.slice();
parentPath.pop();
if (comparePath(parentPath, newPath)) {
return;
}
if (isSubpath(newPath, p)) {
log(Messages.fo_moveFolderToChildError);
return;
}
if (exp.copyElement(p.slice(), newPath)) {
toRemove.push(p);
}
}));
exp.delete(toRemove, cb);
};
exp.restore = function(path, cb) {
if (sframeChan) {
return void sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "restore",
data: {
path
}
}, cb);
}
if (!isInTrashRoot(path)) {
return;
}
var parentPath = path.slice();
parentPath.pop();
var oldPath = find(parentPath).path;
move([ path ], oldPath, cb);
};
exp.addFolder = function(folderPath, name, cb) {
if (sframeChan) {
return void sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "addFolder",
data: {
path: folderPath,
name
}
}, cb);
}
var parentEl = find(folderPath);
var folderName = getAvailableName(parentEl, name || NEW_FOLDER_NAME);
parentEl[folderName] = {};
var newPath = folderPath.slice();
newPath.push(folderName);
cb({
newPath
});
};
exp.delete = function(paths, cb, nocheck) {
if (sframeChan) {
return void sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "delete",
data: {
paths,
nocheck
}
}, cb);
}
cb = cb || function() {};
exp.deleteMultiplePermanently(paths, nocheck, cb);
};
exp.emptyTrash = function(cb) {
cb = cb || function() {};
if (sframeChan) {
return void sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "emptyTrash"
}, cb);
}
files[TRASH] = {};
exp.checkDeletedFiles(cb);
};
exp.ownedInTrash = function(isOwned) {
return getFiles([ TRASH ]).map((function(id) {
var data = isSharedFolder(id) ? files[SHARED_FOLDERS][id] : exp.getFileData(id);
if (!data) {
return;
}
return isOwned(data.owners) ? data.channel : undefined;
})).filter(Boolean);
};
exp.rename = function(path, newName, cb) {
cb = cb || function() {};
if (sframeChan) {
return void sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "rename",
data: {
path,
newName
}
}, cb);
}
if (path.length <= 1) {
logError("Renaming `root` is forbidden");
return;
}
var element = find(path);
if (isFolder(element) && !isSharedFolder(element)) {
var parentPath = path.slice();
var oldName = parentPath.pop();
if (!newName || !newName.trim() || oldName === newName) {
return;
}
var parentEl = find(parentPath);
if (typeof parentEl[newName] !== "undefined") {
log(Messages.fo_existingNameError);
return;
}
parentEl[newName] = element;
delete parentEl[oldName];
if (typeof cb === "function") {
cb();
}
return;
}
var data;
if (isSharedFolder(element)) {
data = files[SHARED_FOLDERS][element];
} else {
data = files[FILES_DATA][element] || files[STATIC_DATA][element];
}
if (!data) {
return;
}
if (files[STATIC_DATA][element]) {
if (!newName || !newName.trim()) {
return void cb();
}
data.name = newName;
cb();
return;
}
if (!newName || newName.trim() === "") {
delete data.filename;
if (typeof cb === "function") {
cb();
}
return;
}
if (getTitle(element, "name") === newName) {
return;
}
data.filename = newName;
if (typeof cb === "function") {
cb();
}
};
exp.getTagsList = function() {
var tags = {};
var data;
var pushTag = function(tag) {
tags[tag] = tags[tag] ? ++tags[tag] : 1;
};
for (var id in files[FILES_DATA]) {
data = files[FILES_DATA][id];
if (!data.tags || !Array.isArray(data.tags)) {
continue;
}
data.tags.forEach(pushTag);
}
return tags;
};
return exp;
};
return module;
};
if (module.exports) {
module.exports = factory(requireCommonUtil(), requireCommonHash(), requireCommonConstants(), requireUserObjectSetter(), requireCrypto(), undefined);
}
})();
})(userObject$1);
return userObject$1.exports;
}
var sharedfolder = {
exports: {}
};
var nthen = {
exports: {}
};
var hasRequiredNthen;
function requireNthen() {
if (hasRequiredNthen) return nthen.exports;
hasRequiredNthen = 1;
(function(module) {
(function() {
var nThen = function(next) {
var funcs = [];
var timeouts = [];
var calls = 0;
var abort;
var waitFor = function(func) {
calls++;
return function() {
if (func) {
func.apply(null, arguments);
}
calls = (calls || 1) - 1;
while (!calls && funcs.length && !abort) {
funcs.shift()(waitFor);
}
};
};
waitFor.abort = function() {
timeouts.forEach(clearTimeout);
abort = 1;
};
var ret = {
nThen: function(next) {
if (!abort) {
if (!calls) {
next(waitFor);
} else {
funcs.push(next);
}
}
return ret;
},
orTimeout: function(func, milliseconds) {
if (abort) {
return ret;
}
if (!milliseconds) {
throw Error("Must specify milliseconds to orTimeout()");
}
var cto;
var timeout = setTimeout((function() {
while (funcs.shift() !== cto) {}
func(waitFor);
calls = (calls || 1) - 1;
while (!calls && funcs.length) {
funcs.shift()(waitFor);
}
}), milliseconds);
funcs.push(cto = function() {
var idx = timeouts.indexOf(timeout);
if (idx > -1) {
timeouts.splice(idx, 1);
clearTimeout(timeout);
return;
}
throw new Error("timeout not listed in array");
});
timeouts.push(timeout);
return ret;
}
};
return ret.nThen(next);
};
{
module.exports = nThen;
}
})();
})(nthen);
return nthen.exports;
}
var hasRequiredSharedfolder;
function requireSharedfolder() {
if (hasRequiredSharedfolder) return sharedfolder.exports;
hasRequiredSharedfolder = 1;
(function(module) {
(() => {
const factory = (Hash, Util, UserObject, Cache, nThen, Crypto, Listmap, ChainPad) => {
var SF = {};
var allSharedFolders = {};
SF.checkMigration = function(secondaryKey, proxy, uo, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
if (!proxy) {
return void cb();
}
if (!secondaryKey) {
return void cb();
}
if (proxy.version >= 2) {
return void cb();
}
if (!proxy.migrateRo) {
return void uo.migrateReadOnly(cb);
}
var done = false;
var to;
var it = setInterval((function() {
if (proxy.version >= 2) {
done = true;
clearTimeout(to);
clearInterval(it);
return void cb();
}
}), 100);
to = setTimeout((function() {
clearInterval(it);
uo.migrateReadOnly((function() {
done = true;
cb();
}));
}), 2e4);
var path = [ "version" ];
proxy.on("change", path, (function() {
if (done) {
return;
}
if (proxy.version >= 2) {
done = true;
clearTimeout(to);
clearInterval(it);
cb();
}
}));
};
SF.migrate = function(channel) {
var sf = allSharedFolders[channel];
if (!sf) {
return;
}
var clients = sf.teams;
if (!Array.isArray(clients) || !clients.length) {
return;
}
var c = clients[0];
if (!c.secondaryKey) {
return;
}
var f = Util.find(c, [ "store", "manager", "folders", c.id ]);
if (!f) {
return;
}
if (!f.proxy || f.proxy.version) {
return;
}
f.userObject.migrateReadOnly((function() {
clients.forEach((function(obj) {
var uo = Util.find(obj, [ "store", "manager", "folders", obj.id, "userObject" ]);
uo.setReadOnly(false, obj.secondarykey);
}));
}));
};
SF.load = function(config, id, data, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var network = config.network;
var store = config.store;
var isNew = config.isNew;
var isNewChannel = config.isNewChannel;
var teamId = store.id;
var handler = store.handleSharedFolder;
var href = store.manager.user.userObject.getHref(data);
var parsed = Hash.parsePadUrl(href);
var secret = Hash.getSecrets("drive", parsed.hash, data.password);
if (!secret.keys) {
store.manager.deprecateProxy(id);
return void cb(null);
}
var secondaryKey = secret.keys.secondaryKey;
nThen((function(waitFor) {
if (config.cache) {
Cache.getChannelCache(secret.channel, waitFor((function(err) {
if (err === "EINVAL") {
waitFor.abort();
store.manager.restrictedProxy(id, secret.channel);
return void cb(null);
}
})));
}
})).nThen((function(waitFor) {
isNewChannel(null, {
channel: secret.channel
}, waitFor((function(obj) {
if (obj.isNew && !isNew) {
store.manager.deprecateProxy(id, secret.channel, obj.reason);
waitFor.abort();
return void cb(null);
}
})));
})).nThen((function() {
var sf = allSharedFolders[secret.channel];
if (sf && sf.readOnly && secondaryKey) {
SF.upgrade(secret.channel, secret);
}
if (sf && sf.ready && sf.rt) {
setTimeout((function() {
var leave = function() {
SF.leave(secret.channel, teamId);
};
store.manager.addProxy(id, sf.rt, leave, secondaryKey);
cb(sf.rt);
}));
sf.teams.push({
cb,
store,
id
});
if (handler) {
handler(id, sf.rt);
}
return;
}
if (sf && !sf.ready && sf.rt) {
sf.teams.push({
cb,
store,
secondaryKey,
id
});
if (handler) {
handler(id, sf.rt);
}
return;
}
sf = allSharedFolders[secret.channel] = {
teams: [ {
cb,
store,
secondaryKey,
id
} ],
readOnly: !Boolean(secondaryKey)
};
var owners = data.owners;
var listmapConfig = {
data: {},
channel: secret.channel,
readOnly: !Boolean(secondaryKey),
crypto: Crypto.createEncryptor(secret.keys),
userName: "sharedFolder",
logLevel: 1,
ChainPad,
classic: true,
network,
Cache,
metadata: {
validateKey: secret.keys.validateKey || undefined,
owners
},
onRejected: config.Store && config.Store.onRejected
};
var rt = sf.rt = Listmap.create(listmapConfig);
rt.proxy.on("cacheready", (function() {
if (!sf.teams) {
return;
}
sf.teams.forEach((function(obj) {
var leave = function() {
SF.leave(secret.channel, obj.store.id);
};
rt.cache = true;
obj.store.manager.addProxy(obj.id, rt, leave, obj.secondaryKey, config.updatePassword);
config.updatePassword = false;
obj.cb(sf.rt);
}));
sf.ready = true;
}));
rt.proxy.on("ready", (function() {
if (isNew && !Object.keys(rt.proxy).length) {
rt.proxy.version = 2;
}
if (!sf.teams) {
return;
}
sf.teams.forEach((function(obj) {
var leave = function() {
SF.leave(secret.channel, obj.store.id);
};
rt.cache = false;
obj.store.manager.addProxy(obj.id, rt, leave, obj.secondaryKey, config.updatePassword);
obj.cb(sf.rt);
}));
sf.ready = true;
}));
rt.proxy.on("error", (function(info) {
if (info && info.error) {
if (info.error === "EDELETED") {
try {
sf.teams.forEach((function(obj) {
obj.store.manager.deprecateProxy(obj.id, secret.channel, info.message);
if (obj.store.handleSharedFolder) {
obj.store.handleSharedFolder(obj.id, null);
}
obj.cb();
}));
} catch (e) {}
delete allSharedFolders[secret.channel];
return void cb();
}
if (info.error === "ERESTRICTED") {
sf.teams.forEach((function(obj) {
obj.store.manager.restrictedProxy(obj.id, secret.channel);
obj.cb();
}));
delete allSharedFolders[secret.channel];
return void cb();
}
}
}));
if (handler) {
handler(id, rt);
}
}));
};
SF.upgrade = function(channel, secret) {
var sf = allSharedFolders[channel];
if (!sf || !sf.readOnly) {
return;
}
if (!sf.rt.setReadOnly) {
return;
}
if (!secret.keys || !secret.keys.editKeyStr) {
return;
}
var crypto = Crypto.createEncryptor(secret.keys);
sf.readOnly = false;
sf.rt.setReadOnly(false, crypto);
};
SF.leave = function(channel, teamId) {
var sf = allSharedFolders[channel];
if (!sf) {
return;
}
var clients = sf.teams;
if (!Array.isArray(clients)) {
return;
}
var idx;
clients.some((function(obj, i) {
if (obj.store.id === teamId) {
if (obj.store.handleSharedFolder) {
obj.store.handleSharedFolder(obj.id, null);
}
idx = i;
return true;
}
}));
if (typeof idx === "undefined") {
return;
}
clients.splice(idx, 1);
if (clients.length) {
return;
}
if (sf.rt && sf.rt.stop) {
sf.rt.stop();
}
};
SF.updatePassword = function(Store, data, network, cb) {
var oldChannel = data.oldChannel;
var href = data.href;
var password = data.password;
var parsed = Hash.parsePadUrl(href);
var secret = Hash.getSecrets(parsed.type, parsed.hash, password);
var sf = allSharedFolders[oldChannel];
if (!sf) {
return void cb({
error: "ENOTFOUND"
});
}
if (sf.rt && sf.rt.stop) {
try {
sf.rt.stop();
} catch (e) {}
}
var nt = nThen;
sf.teams.forEach((function(obj) {
nt = nt((function(waitFor) {
var s = obj.store;
var sfId = obj.id;
var shared = Util.find(s.proxy, [ "drive", UserObject.SHARED_FOLDERS ]) || {};
if (!sfId || !shared[sfId]) {
return;
}
var sf = JSON.parse(JSON.stringify(shared[sfId]));
sf.password = password;
SF.load({
network,
store: s,
updatePassword: true,
Store,
isNewChannel: Store.isNewChannel
}, sfId, sf, waitFor());
if (!s.rpc) {
return;
}
s.rpc.unpin([ oldChannel ], waitFor());
s.rpc.pin([ secret.channel ], waitFor());
})).nThen;
}));
nt((function() {
cb();
}));
};
SF.loadSharedFolders = function(Store, network, store, drive, userObject, waitFor, progress, cache) {
var shared = drive[UserObject.SHARED_FOLDERS] || {};
var steps = Object.keys(shared).length;
var i = 1;
var w = waitFor();
progress = progress || function() {};
nThen((function(waitFor) {
Object.keys(shared).forEach((function(id) {
var sf = shared[id];
SF.load({
network,
store,
Store,
cache,
isNewChannel: Store.isNewChannel
}, id, sf, waitFor((function() {
progress({
progress: i,
max: steps
});
i++;
})));
}));
})).nThen((function() {
setTimeout(w);
}));
};
SF.isSharedFolderChannel = function(chanId) {
return Object.keys(allSharedFolders).includes(chanId);
};
return SF;
};
if (module.exports) {
module.exports = factory(requireCommonHash(), requireCommonUtil(), requireUserObject(), requireCacheStore(), requireNthen(), requireCrypto(), requireChainpadListmap(), requireChainpad_dist());
}
})();
})(sharedfolder);
return sharedfolder.exports;
}
var hasRequiredProxyManager;
function requireProxyManager() {
if (hasRequiredProxyManager) return proxyManager$1.exports;
hasRequiredProxyManager = 1;
(function(module) {
(() => {
const factory = (UserObject, Util, Hash, SF, Messages = {}, Feedback, nThen) => {
let setCustomize = data => {
Messages = data.Messages;
UserObject.setCustomize(data);
};
var getConfig = function(Env) {
var cfg = {};
for (var k in Env.cfg) {
cfg[k] = Env.cfg[k];
}
return cfg;
};
var addProxy = function(Env, id, lm, leave, editKey, force) {
if (Env.folders[id] && !force && !Env.folders[id].restricted) {
if (Env.folders[id].offline && !lm.cache && Env.Store) {
Env.folders[id].offline = false;
if (Env.folders[id].userObject.fixFiles) {
Env.folders[id].userObject.fixFiles();
}
Env.Store.refreshDriveUI();
}
return;
}
var cfg = getConfig(Env);
cfg.sharedFolder = true;
cfg.id = id;
cfg.editKey = editKey;
cfg.rt = lm.realtime;
cfg.readOnly = Boolean(!editKey);
var userObject = UserObject.init(lm.proxy, cfg);
if (userObject.fixFiles) {
userObject.fixFiles();
}
var proxy = lm.proxy;
if (proxy.metadata && proxy.metadata.title) {
var sf = Env.user.proxy[UserObject.SHARED_FOLDERS][id];
if (sf) {
sf.lastTitle = proxy.metadata.title;
}
}
Env.folders[id] = {
proxy: lm.proxy,
userObject,
leave,
restricted: proxy.restricted,
offline: Boolean(lm.cache)
};
if (proxy.on) {
proxy.on("disconnect", (function() {
Env.folders[id].offline = true;
}));
proxy.on("reconnect", (function() {
Env.folders[id].offline = false;
}));
}
return userObject;
};
var removeProxy = function(Env, id) {
var f = Env.folders[id];
if (!f) {
return;
}
f.leave();
delete Env.folders[id];
};
var sendNotification = (Env, sfId, title) => {
var mailbox = Env.store.mailbox;
if (!mailbox) {
return;
}
var team = Env.cfg.teamId;
var box;
if (team) {
let teams = Env.store.modules["team"].getTeamsData();
box = teams[team];
} else {
let md = Env.Store.getMetadata(null, null, (() => {}));
box = md.user;
}
mailbox.sendTo("SF_DELETED", {
sfId,
team,
title
}, {
curvePublic: box.curvePublic,
channel: box.notifications
}, (err => {
console.error(err);
}));
};
var deprecateProxy = function(Env, id, channel, reason) {
if (Env.folders[id] && Env.folders[id].deleting) {
return;
}
if (Env.user.userObject.readOnly) {
var lm = {
proxy: {
deprecated: true
}
};
removeProxy(Env, id);
addProxy(Env, id, lm, (function() {}));
return void Env.Store.refreshDriveUI();
}
if (channel) {
Env.unpinPads([ channel ], (function() {}));
}
if (reason && reason !== "PASSWORD_CHANGE") {
let temp = Util.find(Env, [ "user", "proxy", UserObject.SHARED_FOLDERS ]);
let title = temp[id] && temp[id].lastTitle;
if (title) {
sendNotification(Env, id, title);
}
delete temp[id];
if (Env.Store && Env.Store.refreshDriveUI) {
Env.Store.refreshDriveUI();
}
return;
}
Env.user.userObject.deprecateSharedFolder(id, reason);
removeProxy(Env, id);
if (Env.Store && Env.Store.refreshDriveUI) {
Env.Store.refreshDriveUI();
}
};
var restrictedProxy = function(Env, id) {
var lm = {
proxy: {
restricted: true,
root: {},
filesData: {}
}
};
removeProxy(Env, id);
addProxy(Env, id, lm, (function() {}));
return void Env.Store.refreshDriveUI();
};
var _ownedByMe = function(Env, owners) {
return Array.isArray(owners) && owners.indexOf(Env.edPublic) !== -1;
};
var _ownedByOther = function(Env, owners) {
return Array.isArray(owners) && owners.length && (!Env.edPublic || owners.indexOf(Env.edPublic) === -1);
};
var _getUserObjects = function(Env) {
var userObjects = [ Env.user.userObject ];
var foldersUO = Object.keys(Env.folders).map((function(k) {
return Env.folders[k].userObject;
}));
Array.prototype.push.apply(userObjects, foldersUO);
return userObjects;
};
var _getUserObjectFromId = function(Env, id) {
var userObjects = _getUserObjects(Env);
var userObject = Env.user.userObject;
userObjects.some((function(uo) {
if (Object.keys(uo.getFileData(id)).length) {
userObject = uo;
return true;
}
}));
return userObject;
};
var _getUserObjectPath = function(Env, uo) {
var fId = Number(uo.id);
if (!fId) {
return;
}
var fPath = Env.user.userObject.findFile(fId)[0];
return fPath;
};
var findChannel = function(Env, channel, editable) {
var ret = [];
Env.user.userObject.findChannels([ channel ], true).forEach((function(id) {
var data = Env.user.proxy[UserObject.SHARED_FOLDERS][id];
if (data && !editable) {
data = JSON.parse(JSON.stringify(data));
}
if (!data) {
data = Env.user.userObject.getFileData(id, editable);
}
ret.push({
id,
data,
userObject: Env.user.userObject
});
}));
Object.keys(Env.folders).forEach((function(fId) {
Env.folders[fId].userObject.findChannels([ channel ]).forEach((function(id) {
ret.push({
id,
fId,
data: Env.folders[fId].userObject.getFileData(id, editable),
userObject: Env.folders[fId].userObject
});
}));
}));
return ret;
};
var findHref = function(Env, href) {
var ret = [];
var id = Env.user.userObject.getIdFromHref(href);
if (id) {
ret.push({
data: Env.user.userObject.getFileData(id),
userObject: Env.user.userObject
});
}
Object.keys(Env.folders).forEach((function(fId) {
var id = Env.folders[fId].userObject.getIdFromHref(href);
if (!id) {
return;
}
ret.push({
fId,
data: Env.folders[fId].userObject.getFileData(id),
userObject: Env.folders[fId].userObject
});
}));
return ret;
};
var findFile = function(Env, id) {
var ret = [];
var userObjects = _getUserObjects(Env);
let mainRes = {};
userObjects.forEach((function(uo) {
var fId = Number(uo.id);
let results;
if (!fId) {
let ids = [ id ];
let fIds = userObjects.map((uo => +uo.id)).filter(Boolean);
Array.prototype.push.apply(ids, fIds);
mainRes = uo.findFiles(ids);
results = mainRes[id];
} else {
results = uo.findFile(id);
let fPath = (mainRes[fId] || [])[0];
if (!fPath) {
return;
}
results.forEach((function(p) {
Array.prototype.unshift.apply(p, fPath);
}));
}
Array.prototype.push.apply(ret, results);
}));
return ret;
};
var findFiles = function(Env, ids) {
var ret = {};
var userObjects = _getUserObjects(Env);
let mainRes = {};
userObjects.forEach((function(uo) {
var fId = Number(uo.id);
if (!uo.id) {
let fIds = userObjects.map((uo => +uo.id)).filter(Boolean);
Array.prototype.push.apply(ids, fIds);
}
var results = uo.findFiles(ids);
if (!uo.id) {
mainRes = results;
}
if (fId) {
let fPath = (mainRes[fId] || [])[0];
if (!fPath) {
return;
}
Object.keys(results).forEach((file => {
results[file].forEach((p => {
Array.prototype.unshift.apply(p, fPath);
}));
}));
}
Object.keys(results).forEach((file => {
ret[file] ||= [];
Array.prototype.push.apply(ret[file], results[file]);
}));
}));
return ret;
};
var _findChannels = function(Env, channels, onlyMain) {
if (onlyMain) {
return Env.user.userObject.findChannels(channels);
}
var ret = [];
var userObjects = _getUserObjects(Env);
userObjects.forEach((function(uo) {
var results = uo.findChannels(channels);
Array.prototype.push.apply(ret, results);
}));
ret = Util.deduplicateString(ret);
return ret;
};
var _getFileData = function(Env, id, editable) {
var userObjects = _getUserObjects(Env);
var data = {};
userObjects.some((function(uo) {
data = uo.getFileData(id, editable);
if (data && Object.keys(data).length) {
return true;
}
}));
return data;
};
var getSharedFolderData = function(Env, id) {
var inHistory;
if (Env.isHistoryMode && !Env.folders[id]) {
inHistory = true;
} else if (!Env.folders[id]) {
return {};
}
var proxy = inHistory ? {} : Env.folders[id].proxy;
if (Object.keys(proxy.metadata || {}).length > 1) {
proxy.metadata = {
title: proxy.metadata.title
};
}
var obj = Util.clone(proxy.metadata || {});
for (var k in Env.user.proxy[UserObject.SHARED_FOLDERS][id] || {}) {
if (typeof Env.user.proxy[UserObject.SHARED_FOLDERS][id][k] === "undefined") {
continue;
}
var data = Util.clone(Env.user.proxy[UserObject.SHARED_FOLDERS][id][k]);
if (k === "href" && data.indexOf("#") === -1) {
try {
data = Env.user.userObject.cryptor.decrypt(data);
} catch (e) {}
}
if (k === "href" && data.indexOf("#") === -1) {
data = undefined;
}
obj[k] = data;
}
return obj;
};
var _resolvePath = function(Env, path) {
var res = {
id: null,
userObject: Env.user.userObject,
path
};
if (!Array.isArray(path) || path.length <= 1) {
return res;
}
var current;
var uo = Env.user.userObject;
for (var i = 2; i < path.length; i++) {
current = uo.find(path.slice(0, i));
if (uo.isSharedFolder(current)) {
res = {
id: current,
userObject: Env.folders[current]?.userObject,
path: path.slice(i)
};
break;
}
}
return res;
};
var _resolvePaths = function(Env, paths) {
var main = [];
var folders = {};
paths.forEach((function(path) {
var r = _resolvePath(Env, path);
if (r.id) {
if (!folders[r.id]) {
folders[r.id] = [ r.path ];
} else {
folders[r.id].push(r.path);
}
} else {
main.push(r.path);
}
}));
return {
main,
folders
};
};
var _isInSharedFolder = function(Env, path) {
var resolved = _resolvePath(Env, path);
return typeof resolved.id === "number" ? resolved.id : false;
};
var _isDuplicateOwned = function(Env, path, id) {
if (path && _isInSharedFolder(Env, path)) {
return;
}
var data = _getFileData(Env, id || Env.user.userObject.find(path));
if (!data) {
return;
}
if (!_ownedByMe(Env, data.owners)) {
return;
}
var channel = data.channel;
if (!channel) {
return;
}
var foldersUO = Object.keys(Env.folders).map((function(k) {
return Env.folders[k].userObject;
}));
return foldersUO.some((function(uo) {
return uo.findChannels([ channel ]).length;
}));
};
var _getCopyFromPaths = function(Env, paths, userObject) {
var data = [];
var toNotRemove = [];
paths.forEach((function(path, idx) {
var el = userObject.find(path);
var files = [];
var key = path[path.length - 1];
if (userObject.isFile(el)) {
files.push(el);
} else if (userObject.isSharedFolder(el)) {
files.push(el);
var obj = Env.folders[el].proxy.metadata || {};
if (obj) {
key = obj.title;
}
} else {
try {
el = JSON.parse(JSON.stringify(el));
} catch (e) {
return undefined;
}
userObject.getFilesRecursively(el, files);
}
if (files.some((function(f) {
return userObject.isSharedFolder(f);
}))) {
if (Env.cfg && Env.cfg.log) {
Env.cfg.log(Messages._getKey("fm_moveNestedSF", [ key ]));
}
toNotRemove.unshift(idx);
return;
}
files = Util.deduplicateString(files);
var filesData = {};
files.forEach((function(f) {
filesData[f] = userObject.getFileData(f);
}));
data.push({
el,
data: filesData,
key
});
}));
toNotRemove.forEach((function(idx) {
paths.splice(idx, 1);
}));
return data;
};
var getEditHash = function(Env, channel) {
var res = findChannel(Env, channel);
var stronger;
res.some((function(obj) {
if (!obj || !obj.data || !obj.data.href) {
return;
}
var parsed = Hash.parsePadUrl(obj.data.href);
var parsedHash = parsed.hashData;
if (!parsedHash || parsedHash.mode === "view") {
return;
}
stronger = parsed.hash;
return true;
}));
return stronger;
};
var _move = function(Env, data, cb) {
var resolved = _resolvePaths(Env, data.paths);
var newResolved = _resolvePath(Env, data.newPath);
var copy = data.copy;
if (!newResolved.userObject.isFolder(newResolved.path)) {
return void cb();
}
nThen((function(waitFor) {
if (resolved.main.length) {
if (!newResolved.id) {
Env.user.userObject.move(resolved.main, newResolved.path, waitFor());
} else {
var toCopy = _getCopyFromPaths(Env, resolved.main, Env.user.userObject);
var newUserObject = newResolved.userObject;
toCopy.forEach((function(obj) {
newUserObject.copyFromOtherDrive(newResolved.path, obj.el, obj.data, obj.key);
}));
if (copy) {
return;
}
if (resolved.main.length) {
Env.user.userObject.delete(resolved.main, waitFor());
}
}
}
var folderIds = Object.keys(resolved.folders);
if (folderIds.length) {
folderIds.forEach((function(fIdStr) {
var fId = Number(fIdStr);
var paths = resolved.folders[fId];
if (newResolved.id === fId) {
newResolved.userObject.move(paths, newResolved.path, waitFor());
} else {
var uoFrom = Env.folders[fId].userObject;
var uoTo = newResolved.userObject;
var toCopy = _getCopyFromPaths(Env, paths, uoFrom);
toCopy.forEach((function(obj) {
uoTo.copyFromOtherDrive(newResolved.path, obj.el, obj.data, obj.key);
}));
if (copy) {
return;
}
uoFrom.delete(paths, waitFor());
}
}));
}
})).nThen((function() {
cb();
}));
};
var _restore = function(Env, data, cb) {
var userObject = Env.user.userObject;
data = data || {};
userObject.restore(data.path, cb);
};
var _addFolder = function(Env, data, cb) {
data = data || {};
var resolved = _resolvePath(Env, data.path);
if (!resolved || !resolved.userObject) {
return void cb({
error: "E_NOTFOUND"
});
}
resolved.userObject.addFolder(resolved.path, data.name, (function(obj) {
if (obj.newPath && resolved.id) {
var fPath = _getUserObjectPath(Env, resolved.userObject);
if (fPath) {
Array.prototype.unshift.apply(obj.newPath, fPath);
}
}
cb(obj);
}));
};
var _addSharedFolder = function(Env, data, cb) {
data = data || {};
var resolved = _resolvePath(Env, data.path);
if (!resolved || !resolved.userObject) {
return void cb({
error: "E_NOTFOUND"
});
}
if (resolved.id) {
return void cb({
error: "EINVAL"
});
}
if (!Env.pinPads) {
return void cb({
error: "EAUTH"
});
}
var folderData = data.folderData || {};
var id;
nThen((function() {
if (data.folderData) {
return;
}
var hash = Hash.createRandomHash("drive", data.password);
var secret = Hash.getSecrets("drive", hash, data.password);
var hashes = Hash.getHashes(secret);
folderData = {
href: "/drive/#" + hashes.editHash,
roHref: "/drive/#" + hashes.viewHash,
channel: secret.channel,
lastTitle: data.name,
ctime: +new Date
};
if (data.password) {
folderData.password = data.password;
}
if (data.owned) {
folderData.owners = [ Env.edPublic ];
}
})).nThen((function(waitFor) {
Env.Store.getPadMetadata(null, {
channel: folderData.channel
}, waitFor((function(obj) {
if (obj && (obj.error || obj.rejected)) {
waitFor.abort();
return void cb({
error: obj.error || "ERESTRICTED"
});
}
})));
})).nThen((function(waitFor) {
Env.pinPads([ folderData.channel ], waitFor());
})).nThen((function(waitFor) {
Env.user.userObject.pushSharedFolder(folderData, waitFor((function(err, folderId) {
if (err === "EEXISTS" && folderData.href && folderId) {
var parsed = Hash.parsePadUrl(folderData.href);
var secret = Hash.getSecrets("drive", parsed.hash, folderData.password);
SF.upgrade(secret.channel, secret);
Env.folders[folderId].userObject.setReadOnly(false, secret.keys.secondaryKey);
waitFor.abort();
return void cb(folderId);
}
if (err === "EEXISTS" && folderId) {
waitFor.abort();
return void cb(folderId);
}
if (err) {
waitFor.abort();
return void cb(err);
}
id = folderId;
})));
})).nThen((function(waitFor) {
Env.user.userObject.add(id, resolved.path);
Env.loadSharedFolder(id, folderData, waitFor((function(rt) {
if (!rt) {
waitFor.abort();
return void cb({
error: "EDELETED"
});
}
if (!rt.proxy.metadata) {
rt.proxy.metadata = {
title: data.name || Messages.fm_newFolder
};
}
if (data.folderData) {
Env.Store.getPadMetadata(null, {
channel: folderData.channel
}, (function(md) {
var fData = Env.user.proxy[UserObject.SHARED_FOLDERS][id];
if (md.owners) {
fData.owners = md.owners;
}
if (md.expire) {
fData.expire = +md.expire;
}
}));
}
})), !Boolean(data.folderData));
})).nThen((function() {
Env.onSync((function() {
cb(id);
}));
}));
};
var _addLink = function(Env, data, cb) {
data = data || {};
var resolved = _resolvePath(Env, data.path);
if (!resolved || !resolved.userObject) {
return void cb({
error: "E_NOTFOUND"
});
}
var uo = resolved.userObject;
var now = +new Date;
uo.pushLink({
name: data.name,
href: data.href,
atime: now,
ctime: now
}, (function(e, id) {
if (e) {
return void cb({
error: e
});
}
uo.add(id, resolved.path);
Env.onSync(cb);
}));
};
var _restoreSharedFolder = function(Env, _data, cb) {
var fId = _data.id;
var newPassword = _data.password;
var temp = Util.find(Env, [ "user", "proxy", UserObject.SHARED_FOLDERS_TEMP ]);
var data = temp && temp[fId];
if (!data) {
return void cb({
error: "EINVAL"
});
}
if (!Env.Store) {
return void cb({
error: "ESTORE"
});
}
var href = Env.user.userObject.getHref ? Env.user.userObject.getHref(data) : data.href;
var isNew = false;
nThen((function(waitFor) {
Env.Store.isNewChannel(null, {
href,
password: newPassword
}, waitFor((function(obj) {
if (!obj || obj.error) {
isNew = false;
return;
}
isNew = obj.isNew;
})));
})).nThen((function() {
if (isNew) {
return void cb({
error: "ENOTFOUND"
});
}
var newData = Util.clone(data);
var parsed = Hash.parsePadUrl(href);
var secret = Hash.getSecrets(parsed.type, parsed.hash, newPassword);
newData.password = newPassword;
newData.channel = secret.channel;
if (secret.keys.editKeyStr) {
newData.href = "/drive/#" + Hash.getEditHashFromKeys(secret);
}
newData.roHref = "/drive/#" + Hash.getViewHashFromKeys(secret);
delete newData.legacy;
_addSharedFolder(Env, {
path: [ "root" ],
folderData: newData
}, (function() {
delete temp[fId];
Env.onSync(cb);
}));
}));
};
var _convertFolderToSharedFolder = function(Env, data, cb) {
var path = data.path;
var folderElement = Env.user.userObject.find(path);
if (path.length <= 1 || path[0] !== UserObject.ROOT) {
return void cb({
error: "E_INVAL_PATH"
});
}
if (_isInSharedFolder(Env, path)) {
return void cb({
error: "E_INVAL_NESTING"
});
}
if (Env.user.userObject.hasSubSharedFolder(folderElement)) {
return void cb({
error: "E_INVAL_NESTING"
});
}
var parentPath = path.slice(0, -1);
var parentFolder = Env.user.userObject.find(parentPath);
var folderName = path[path.length - 1];
var SFId;
nThen((function(waitFor) {
_addSharedFolder(Env, {
path: parentPath,
name: folderName,
owned: data.owned,
password: data.password || ""
}, waitFor((function(id) {
if (typeof id === "object" && id && id.error) {
waitFor.abort();
return void cb(id);
} else {
SFId = id;
}
})));
})).nThen((function(waitFor) {
if (!SFId) {
waitFor.abort();
return void cb({
error: "E_NO_ID"
});
}
var paths = [];
for (var el in folderElement) {
if (Env.user.userObject.isFolder(folderElement[el]) || Env.user.userObject.isFile(folderElement[el])) {
paths.push(path.concat(el));
}
}
var SFKey;
Object.keys(parentFolder).some((function(el) {
if (parentFolder[el] === SFId) {
SFKey = el;
return true;
}
}));
if (!SFKey) {
waitFor.abort();
return void cb({
error: "E_NO_KEY"
});
}
var newPath = parentPath.concat(SFKey).concat(UserObject.ROOT);
_move(Env, {
paths,
newPath,
copy: false
}, waitFor());
})).nThen((function(waitFor) {
var paths = [];
Object.keys(folderElement).forEach((function(el) {
if (!Env.user.userObject.isFile(folderElement[el])) {
return;
}
var data = Env.user.userObject.getFileData(folderElement[el]);
if (!data || !_ownedByMe(Env, data.owners)) {
return;
}
paths.push(path.concat(el));
}));
_move(Env, {
paths,
newPath: [ UserObject.ROOT ],
copy: false
}, waitFor());
})).nThen((function() {
var sharedFolderElement = Env.user.proxy[UserObject.SHARED_FOLDERS][SFId];
var metadata = Env.user.userObject.getFolderData(folderElement);
for (var key in metadata) {
if (key === "metadata") {
continue;
}
sharedFolderElement[key] = metadata[key];
}
Env.user.userObject.delete([ path ], (function() {
cb({
fId: SFId
});
}));
}));
};
var _delete = function(Env, data, cb) {
data = data || {};
var resolved = data.resolved || _resolvePaths(Env, data.paths);
if (!resolved.main.length && !Object.keys(resolved.folders).length) {
return void cb({
error: "E_NOTFOUND"
});
}
if (data.paths && data.paths.length === 1 && data.paths[0][0] === UserObject.SHARED_FOLDERS_TEMP) {
var temp = Util.find(Env, [ "user", "proxy", UserObject.SHARED_FOLDERS_TEMP ]);
delete temp[data.paths[0][1]];
return void Env.onSync(cb);
}
var toUnpin = [];
nThen((function(waitFor) {
if (resolved.main.length) {
var uo = Env.user.userObject;
if (Util.find(Env.settings, [ "drive", "hideDuplicate" ])) {
resolved.main.forEach((function(p) {
var el = uo.find(p);
if (p[0] === UserObject.FILES_DATA) {
return;
}
if (uo.isFile(el) || uo.isSharedFolder(el)) {
return;
}
var arr = [];
uo.getFilesRecursively(el, arr);
arr.forEach((function(id) {
if (_isDuplicateOwned(Env, null, id)) {
Env.user.userObject.add(Number(id), [ UserObject.ROOT ]);
}
}));
}));
}
uo.delete(resolved.main, waitFor((function(err, _toUnpin) {
if (!Env.unpinPads || !_toUnpin) {
return;
}
Array.prototype.push.apply(toUnpin, _toUnpin);
})));
}
})).nThen((function(waitFor) {
Object.keys(resolved.folders).forEach((function(id) {
Env.folders[id].userObject.delete(resolved.folders[id], waitFor((function(err, _toUnpin) {
if (!Env.unpinPads || !_toUnpin) {
return;
}
Array.prototype.push.apply(toUnpin, _toUnpin);
})));
}));
})).nThen((function(waitFor) {
if (!Env.unpinPads) {
return;
}
toUnpin = Util.deduplicateString(toUnpin);
var toKeep = [];
_findChannels(Env, toUnpin).forEach((function(id) {
var data = _getFileData(Env, id);
var arr = [ data.channel ];
if (data.answersChannel) {
arr.push(data.answersChannel);
}
if (data.rtChannel) {
arr.push(data.rtChannel);
}
if (data.lastVersion) {
arr.push(Hash.hrefToHexChannelId(data.lastVersion));
}
Array.prototype.push.apply(toKeep, arr);
}));
var unpinList = [];
toUnpin.forEach((function(chan) {
if (toKeep.indexOf(chan) === -1) {
unpinList.push(chan);
Env.Store.checkDeletedPad(chan);
}
}));
Env.unpinPads(unpinList, waitFor((function(response) {
if (response && response.error) {
return console.error(response.error);
}
})));
})).nThen((function() {
cb();
}));
};
var _deleteOwned = function(Env, data, cb) {
data = data || {};
var resolved = _resolvePaths(Env, data.paths || []);
if (!data.channel && !resolved.main.length && !Object.keys(resolved.folders).length) {
return void cb({
error: "E_NOTFOUND"
});
}
var toDelete = {
main: [],
folders: {}
};
var todo = function(channel, uo, p, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var chan = channel;
if (!chan && uo) {
var el = uo.find(p);
if (!uo.isFile(el) && !uo.isSharedFolder(el)) {
return;
}
var data = uo.isFile(el) ? uo.getFileData(el) : getSharedFolderData(Env, el);
chan = data.channel;
}
var fId;
Object.keys(Env.user.proxy[UserObject.SHARED_FOLDERS] || {}).some((function(id) {
var sfData = Env.user.proxy[UserObject.SHARED_FOLDERS][id] || {};
if (sfData.channel === chan) {
fId = Number(id);
Env.folders[id].deleting = true;
return true;
}
}));
Env.removeOwnedChannel(chan, (function(obj) {
if (obj && obj.error && obj.error !== "ENOENT") {
if (fId && Env.folders[fId] && Env.folders[fId].deleting) {
delete Env.folders[fId].deleting;
}
Feedback.send("ERROR_DELETING_OWNED_PAD=" + chan + "|" + obj.error, true);
return void cb();
}
var ids = _findChannels(Env, [ chan ]);
if (fId) {
ids.push(fId);
}
if (!ids.length) {
toDelete = undefined;
return void cb();
}
ids.forEach((function(id) {
var paths = findFile(Env, id);
var _resolved = _resolvePaths(Env, paths);
Array.prototype.push.apply(toDelete.main, _resolved.main);
Object.keys(_resolved.folders).forEach((function(fId) {
if (toDelete.folders[fId]) {
Array.prototype.push.apply(toDelete.folders[fId], _resolved.folders[fId]);
} else {
toDelete.folders[fId] = _resolved.folders[fId];
}
}));
}));
cb();
}));
};
nThen((function(w) {
if (data.channel) {
todo(data.channel, null, null, w());
}
resolved.main.forEach((function(p) {
todo(null, Env.user.userObject, p, w());
}));
Object.keys(resolved.folders).forEach((function(id) {
var uo = Env.folders[id].userObject;
resolved.folders[id].forEach((function(p) {
todo(null, uo, p, w());
}));
}));
})).nThen((function() {
if (!toDelete) {
cb();
} else {
_delete(Env, {
resolved: toDelete
}, cb);
}
if (data.channel) {
Env.Store.refreshDriveUI();
}
}));
};
var _emptyTrash = function(Env, data, cb) {
nThen((function(waitFor) {
if (data && data.deleteOwned) {
var owned = Env.user.userObject.ownedInTrash((function(owners) {
return _ownedByMe(Env, owners);
}));
var n = nThen;
owned.forEach((function(chan) {
n = n((function(w) {
Env.removeOwnedChannel(chan, w((function(obj) {
setTimeout(w(), 50);
if (obj && obj.error && obj.error !== "ENOENT") {
console.error(obj.error, chan);
Feedback.send("ERROR_EMPTYTRASH_OWNED=" + chan + "|" + obj.error, true);
}
console.warn("DELETED", chan);
})));
})).nThen;
}));
n(waitFor());
}
Env.user.userObject.emptyTrash(waitFor((function(err, toClean) {
var nn = nThen;
setTimeout(waitFor((function() {
if (!Array.isArray(toClean)) {
return;
}
var done = waitFor();
var toCheck = Util.deduplicateString(toClean);
var toUnpin = [];
toCheck.forEach((function(channel) {
nn = nn((function(w) {
var data = findChannel(Env, channel, true);
if (!data.length) {
toUnpin.push(channel);
}
Env.Store.checkDeletedPad(channel, w());
})).nThen;
}));
nn((function() {
Env.unpinPads(toUnpin, (function() {
done();
}));
}));
})));
})));
})).nThen(cb);
};
var _rename = function(Env, data, cb) {
data = data || {};
var resolved = _resolvePath(Env, data.path);
if (!resolved || !resolved.userObject) {
return void cb({
error: "E_NOTFOUND"
});
}
if (!resolved.id) {
var el = Env.user.userObject.find(resolved.path);
if (Env.user.userObject.isSharedFolder(el) && Env.folders[el]) {
Env.folders[el].proxy.metadata.title = data.newName || Messages.fm_folder;
Env.user.proxy[UserObject.SHARED_FOLDERS][el].lastTitle = data.newName || Messages.fm_folder;
return void cb();
}
}
resolved.userObject.rename(resolved.path, data.newName, cb);
};
var _setFolderData = function(Env, data, cb) {
data = data || {};
var resolved = _resolvePath(Env, data.path);
if (!resolved || !resolved.userObject) {
return void cb({
error: "E_NOTFOUND"
});
}
if (!resolved.id) {
var el = Env.user.userObject.find(resolved.path);
if (Env.user.userObject.isSharedFolder(el) && Env.folders[el]) {
Env.user.proxy[UserObject.SHARED_FOLDERS][el][data.key] = data.value;
return void Env.onSync(cb);
}
}
resolved.userObject.setFolderData(resolved.path, data.key, data.value, (function() {
Env.onSync(cb);
}));
};
var _updateStaticAccess = function(Env, id, cb) {
var uo = _getUserObjectFromId(Env, id);
var sd = uo.getFileData(id, true);
sd.atime = +new Date;
Env.onSync(cb);
};
var COMMANDS = {
move: _move,
restore: _restore,
addFolder: _addFolder,
addSharedFolder: _addSharedFolder,
addLink: _addLink,
restoreSharedFolder: _restoreSharedFolder,
convertFolderToSharedFolder: _convertFolderToSharedFolder,
delete: _delete,
deleteOwned: _deleteOwned,
emptyTrash: _emptyTrash,
rename: _rename,
setFolderData: _setFolderData,
updateStaticAccess: _updateStaticAccess
};
var onCommand = function(Env, cmdData, cb) {
var cmd = cmdData.cmd;
var data = cmdData.data || {};
var method = COMMANDS[cmd];
if (typeof method === "function") {
return void method(Env, data, cb);
}
cb();
};
var setPadAttribute = function(Env, data, cb) {
cb = cb || function() {};
if (!data.attr || !data.attr.trim()) {
return void cb("E_INVAL_ATTR");
}
var sfId = Env.user.userObject.getSFIdFromHref(data.href);
if (sfId) {
if (data.attr === "href") {
data.value = Env.user.userObject.cryptor.encrypt(data.value);
}
Env.user.proxy[UserObject.SHARED_FOLDERS][sfId][data.attr] = data.value;
}
var datas = findHref(Env, data.href);
var nt = nThen;
datas.forEach((function(d) {
nt = nt((function(waitFor) {
d.userObject.setPadAttribute(data.href, data.attr, data.value, waitFor());
})).nThen;
}));
nt((function() {
cb();
}));
};
var getPadAttribute = function(Env, data, cb) {
cb = cb || function() {};
var sfId = Env.user.userObject.getSFIdFromHref(data.href);
if (sfId) {
var sfData = getSharedFolderData(Env, sfId);
var sfValue = data.attr ? sfData[data.attr] : JSON.parse(JSON.stringify(sfData));
setTimeout((function() {
cb(null, {
value: sfValue,
atime: 1
});
}));
return;
}
var datas = findHref(Env, data.href);
var res = {};
datas.forEach((function(d) {
var atime = d.data.atime;
var value = data.attr ? d.data[data.attr] : JSON.parse(JSON.stringify(d.data));
if (!res.value || res.atime < atime) {
res.atime = atime;
res.value = value;
}
}));
setTimeout((function() {
cb(null, res);
}));
};
var getTagsList = function(Env) {
var list = {};
var userObjects = _getUserObjects(Env);
userObjects.forEach((function(uo) {
var l = uo.getTagsList();
Object.keys(l).forEach((function(t) {
list[t] = list[t] ? list[t] + l[t] : l[t];
}));
}));
return list;
};
var getSecureFilesList = function(Env, where) {
var userObjects = _getUserObjects(Env);
var list = [];
var channels = [];
userObjects.forEach((function(uo) {
var toPush = uo.getFiles(where).map((function(id) {
return {
id,
data: uo.getFileData(id)
};
})).filter((function(d) {
if (channels.indexOf(d.data.channel || d.id) === -1) {
channels.push(d.data.channel || d.id);
return true;
}
}));
Array.prototype.push.apply(list, toPush);
}));
return list;
};
var excludeInvalidIdentifiers = function(result) {
return result.filter((function(channel) {
if (typeof channel !== "string") {
return;
}
return [ 32, 48 ].indexOf(channel.length) !== -1;
}));
};
var getChannelsList = function(Env, type) {
var result = [];
var addChannel = function(userObject) {
if (type === "expirable") {
return function(fileId) {
var data = userObject.getFileData(fileId);
if (!data) {
return;
}
if (result.indexOf(data.channel) !== -1) {
return;
}
if (_ownedByOther(Env, data.owners) || data.expire && data.expire < +new Date) {
result.push(data.channel);
}
};
}
if (type === "owned") {
return function(fileId) {
var data = userObject.getFileData(fileId);
if (!data) {
return;
}
if (result.indexOf(data.channel) !== -1) {
return;
}
if (_ownedByMe(Env, data.owners)) {
result.push(data.channel);
}
};
}
if (type === "pin") {
return function(fileId) {
var data = userObject.getFileData(fileId);
if (!data) {
return;
}
if (data.lastVersion) {
var otherChan = Hash.hrefToHexChannelId(data.lastVersion);
if (result.indexOf(otherChan) === -1) {
result.push(otherChan);
}
}
if (data.answersChannel && result.indexOf(data.answersChannel) === -1) {
result.push(data.answersChannel);
}
if (data.rtChannel && result.indexOf(data.rtChannel) === -1) {
result.push(data.rtChannel);
}
if (data.ooImages && Array.isArray(data.ooImages)) {
Array.prototype.push.apply(result, data.ooImages);
}
if (result.indexOf(data.channel) === -1) {
result.push(data.channel);
}
};
}
};
if (type === "owned" && !Env.edPublic) {
return excludeInvalidIdentifiers(result);
}
if (type === "pin" && !Env.edPublic) {
return excludeInvalidIdentifiers(result);
}
var userObjects = _getUserObjects(Env);
userObjects.forEach((function(uo) {
var files = uo.getFiles([ UserObject.FILES_DATA ]);
files.forEach(addChannel(uo));
}));
if (type === "owned") {
var sfOwned = Object.keys(Env.user.proxy[UserObject.SHARED_FOLDERS]).filter((function(fId) {
var owners = Env.user.proxy[UserObject.SHARED_FOLDERS][fId].owners;
if (_ownedByMe(Env, owners)) {
return true;
}
})).map((function(fId) {
return Env.user.proxy[UserObject.SHARED_FOLDERS][fId].channel;
}));
Array.prototype.push.apply(result, sfOwned);
}
if (type === "pin") {
var sfChannels = Object.keys(Env.folders).map((function(fId) {
try {
return Env.user.proxy[UserObject.SHARED_FOLDERS][fId].channel;
} catch (err) {
console.error(err);
}
})).filter(Boolean);
Array.prototype.push.apply(result, sfChannels);
}
return excludeInvalidIdentifiers(result);
};
var addPad = function(Env, path, pad, cb) {
var uo = Env.user.userObject;
var p = [ "root" ];
if (path) {
var resolved = _resolvePath(Env, path);
uo = resolved.userObject;
p = resolved.path;
}
var todo = function() {
var error;
nThen((function(waitFor) {
uo.pushData(pad, waitFor((function(e, id) {
if (e) {
error = e;
return;
}
uo.add(id, p);
})));
})).nThen((function() {
cb(error);
}));
};
if (!Env.pinPads) {
return void todo();
}
Env.pinPads([ pad.channel ], (function(obj) {
if (obj && obj.error) {
return void cb(obj.error);
}
todo();
}));
};
var create = function(proxy, data, uoConfig) {
var Env = {
pinPads: data.pin,
unpinPads: data.unpin,
onSync: data.onSync,
Store: data.Store,
store: data.store,
removeOwnedChannel: data.removeOwnedChannel,
loadSharedFolder: data.loadSharedFolder,
cfg: uoConfig,
edPublic: data.edPublic,
settings: data.settings,
user: {
proxy
},
folders: {}
};
uoConfig.removeProxy = function(id) {
removeProxy(Env, id);
};
Env.user.userObject = UserObject.init(proxy, uoConfig);
var callWithEnv = function(f) {
return function() {
[].unshift.call(arguments, Env);
return f.apply(null, arguments);
};
};
var addPin = function(pin, unpin) {
Env.pinPads = pin;
Env.unpinPads = unpin;
};
var removePin = function() {
delete Env.pinPads;
delete Env.unpinPads;
};
return {
addProxy: callWithEnv(addProxy),
removeProxy: callWithEnv(removeProxy),
deprecateProxy: callWithEnv(deprecateProxy),
restrictedProxy: callWithEnv(restrictedProxy),
addSharedFolder: callWithEnv(_addSharedFolder),
addPin,
removePin,
command: callWithEnv(onCommand),
getPadAttribute: callWithEnv(getPadAttribute),
setPadAttribute: callWithEnv(setPadAttribute),
getTagsList: callWithEnv(getTagsList),
getSecureFilesList: callWithEnv(getSecureFilesList),
getSharedFolderData: callWithEnv(getSharedFolderData),
getChannelsList: callWithEnv(getChannelsList),
addPad: callWithEnv(addPad),
delete: callWithEnv(_delete),
deleteOwned: callWithEnv(_deleteOwned),
findChannel: callWithEnv(findChannel),
findHref: callWithEnv(findHref),
findFile: callWithEnv(findFile),
getEditHash: callWithEnv(getEditHash),
user: Env.user,
folders: Env.folders
};
};
var renameInner = function(Env, path, newName, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "rename",
data: {
path,
newName
}
}, cb);
};
var moveInner = function(Env, paths, newPath, cb, copy) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "move",
data: {
paths,
newPath,
copy
}
}, cb);
};
var emptyTrashInner = function(Env, deleteOwned, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "emptyTrash",
data: {
deleteOwned
}
}, cb);
};
var addFolderInner = function(Env, path, name, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "addFolder",
data: {
path,
name
}
}, cb);
};
var addSharedFolderInner = function(Env, path, data, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "addSharedFolder",
data: {
path,
name: data.name,
owned: data.owned,
password: data.password
}
}, cb);
};
var addLinkInner = function(Env, path, data, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "addLink",
data: {
path,
name: data.name,
href: data.url
}
}, cb);
};
var restoreSharedFolderInner = function(Env, fId, password, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "restoreSharedFolder",
data: {
id: fId,
password
}
}, cb);
};
var convertFolderToSharedFolderInner = function(Env, path, owned, password, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "convertFolderToSharedFolder",
data: {
path,
owned,
password
}
}, cb);
};
var deleteInner = function(Env, paths, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "delete",
data: {
paths
}
}, cb);
};
var deleteOwnedInner = function(Env, paths, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "deleteOwned",
data: {
paths
}
}, cb);
};
var restoreInner = function(Env, path, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "restore",
data: {
path
}
}, cb);
};
var setFolderDataInner = function(Env, data, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "setFolderData",
data
}, cb);
};
var updateStaticAccessInner = function(Env, id, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "updateStaticAccess",
data: id
}, cb);
};
var findChannels = _findChannels;
var getFileData = _getFileData;
var getUserObjectPath = _getUserObjectPath;
var find = function(Env, path, fId) {
if (fId) {
return Env.folders[fId].userObject.find(path);
}
var resolved = _resolvePath(Env, path);
return resolved.userObject.find(resolved.path);
};
var getTitle = function(Env, id, type) {
var uo = _getUserObjectFromId(Env, id);
return String(uo.getTitle(id, type));
};
var isStaticFile = function(Env, id) {
var uo = _getUserObjectFromId(Env, id);
return uo.isStaticFile(id);
};
var isReadOnlyFile = function(Env, id) {
var uo = _getUserObjectFromId(Env, id);
return uo.isReadOnlyFile(id);
};
var getFiles = function(Env, categories) {
var files = [];
var userObjects = _getUserObjects(Env);
userObjects.forEach((function(uo) {
Array.prototype.push.apply(files, uo.getFiles(categories));
}));
files = Util.deduplicateString(files);
return files;
};
var search = function(Env, value) {
var ret = [];
var userObjects = _getUserObjects(Env);
userObjects.forEach((function(uo) {
var fPath = _getUserObjectPath(Env, uo);
var results = uo.search(value);
if (!results.length) {
return;
}
if (fPath) {
results.forEach((function(r) {
r.inSharedFolder = true;
r.paths.forEach((function(p) {
Array.prototype.unshift.apply(p, fPath);
}));
}));
}
Array.prototype.push.apply(ret, results);
}));
return ret;
};
var getRecentPads = function(Env) {
var files = [];
var userObjects = _getUserObjects(Env);
userObjects.forEach((function(uo) {
var data = uo.getFiles([ UserObject.FILES_DATA, UserObject.STATIC_DATA ]).map((function(id) {
return [ Number(id), uo.getFileData(id) ];
}));
Array.prototype.push.apply(files, data);
}));
var sorted = files.filter((function(a) {
return a[1].atime;
})).sort((function(a, b) {
return b[1].atime - a[1].atime;
}));
return sorted;
};
var getOwnedPads = function(Env) {
return Env.user.userObject.getOwnedPads(Env.edPublic);
};
var setHistoryMode = function(Env, flag) {
Env.isHistoryMode = Boolean(flag);
};
var getFolderData = function(Env, path) {
var resolved = _resolvePath(Env, path);
if (!resolved || !resolved.userObject) {
return {};
}
if (!resolved.id) {
var el = Env.user.userObject.find(resolved.path);
if (Env.user.userObject.isSharedFolder(el)) {
return getSharedFolderData(Env, el);
}
}
var folder = resolved.userObject.find(resolved.path);
return resolved.userObject.getFolderData(folder);
};
var isInSharedFolder = _isInSharedFolder;
var isValidDrive = function(Env, obj) {
return Env.user.userObject.isValidDrive(obj);
};
var isFile = function(Env, el, allowStr) {
return Env.user.userObject.isFile(el, allowStr);
};
var isFolder = function(Env, el) {
return Env.user.userObject.isFolder(el);
};
var isSharedFolder = function(Env, el) {
return Env.user.userObject.isSharedFolder(el);
};
var isFolderEmpty = function(Env, el) {
if (Env.folders[el]) {
var uo = Env.folders[el].userObject;
return uo.isFolderEmpty(uo.find[uo.ROOT]);
}
return Env.user.userObject.isFolderEmpty(el);
};
var isPathIn = function(Env, path, categories) {
return Env.user.userObject.isPathIn(path, categories);
};
var isSubpath = function(Env, path, parentPath) {
return Env.user.userObject.isSubpath(path, parentPath);
};
var isInTrashRoot = function(Env, path) {
return Env.user.userObject.isInTrashRoot(path);
};
var comparePath = function(Env, a, b) {
return Env.user.userObject.comparePath(a, b);
};
var hasSubfolder = function(Env, el, trashRoot) {
if (Env.folders[el]) {
var uo = Env.folders[el].userObject;
return uo.hasSubfolder(uo.find[uo.ROOT]);
}
return Env.user.userObject.hasSubfolder(el, trashRoot);
};
var hasSubSharedFolder = function(Env, el) {
return Env.user.userObject.hasSubSharedFolder(el);
};
var hasFile = function(Env, el, trashRoot) {
if (Env.folders[el]) {
var uo = Env.folders[el].userObject;
return uo.hasFile(uo.find[uo.ROOT]);
}
return Env.user.userObject.hasFile(el, trashRoot);
};
var ownedInTrash = function(Env) {
return Env.user.userObject.ownedInTrash((function(owners) {
return _ownedByMe(Env, owners);
}));
};
var isDuplicateOwned = _isDuplicateOwned;
var createInner = function(proxy, sframeChan, edPublic, uoConfig) {
var Env = {
cfg: uoConfig,
sframeChan,
edPublic,
user: {
proxy,
userObject: UserObject.init(proxy, uoConfig)
},
folders: {}
};
var callWithEnv = function(f) {
return function() {
[].unshift.call(arguments, Env);
return f.apply(null, arguments);
};
};
return {
addProxy: callWithEnv(addProxy),
removeProxy: callWithEnv(removeProxy),
setHistoryMode: callWithEnv(setHistoryMode),
rename: callWithEnv(renameInner),
move: callWithEnv(moveInner),
emptyTrash: callWithEnv(emptyTrashInner),
addFolder: callWithEnv(addFolderInner),
addSharedFolder: callWithEnv(addSharedFolderInner),
addLink: callWithEnv(addLinkInner),
restoreSharedFolder: callWithEnv(restoreSharedFolderInner),
convertFolderToSharedFolder: callWithEnv(convertFolderToSharedFolderInner),
delete: callWithEnv(deleteInner),
deleteOwned: callWithEnv(deleteOwnedInner),
restore: callWithEnv(restoreInner),
setFolderData: callWithEnv(setFolderDataInner),
updateStaticAccess: callWithEnv(updateStaticAccessInner),
getFileData: callWithEnv(getFileData),
find: callWithEnv(find),
getTitle: callWithEnv(getTitle),
isReadOnlyFile: callWithEnv(isReadOnlyFile),
isStaticFile: callWithEnv(isStaticFile),
getFiles: callWithEnv(getFiles),
search: callWithEnv(search),
getRecentPads: callWithEnv(getRecentPads),
getOwnedPads: callWithEnv(getOwnedPads),
getTagsList: callWithEnv(getTagsList),
findFile: callWithEnv(findFile),
findFiles: callWithEnv(findFiles),
findChannels: callWithEnv(findChannels),
getSharedFolderData: callWithEnv(getSharedFolderData),
getFolderData: callWithEnv(getFolderData),
isInSharedFolder: callWithEnv(isInSharedFolder),
getUserObjectPath: callWithEnv(getUserObjectPath),
isDuplicateOwned: callWithEnv(isDuplicateOwned),
ownedInTrash: callWithEnv(ownedInTrash),
isValidDrive: callWithEnv(isValidDrive),
isFile: callWithEnv(isFile),
isFolder: callWithEnv(isFolder),
isSharedFolder: callWithEnv(isSharedFolder),
isFolderEmpty: callWithEnv(isFolderEmpty),
isPathIn: callWithEnv(isPathIn),
isSubpath: callWithEnv(isSubpath),
isInTrashRoot: callWithEnv(isInTrashRoot),
comparePath: callWithEnv(comparePath),
hasSubfolder: callWithEnv(hasSubfolder),
hasSubSharedFolder: callWithEnv(hasSubSharedFolder),
hasFile: callWithEnv(hasFile),
user: Env.user,
folders: Env.folders
};
};
return {
setCustomize,
create,
createInner
};
};
if (module.exports) {
module.exports = factory(requireUserObject(), requireCommonUtil(), requireCommonHash(), requireSharedfolder(), undefined, requireCommonFeedback(), requireNthen());
}
})();
})(proxyManager$1);
return proxyManager$1.exports;
}
var proxyManagerExports = requireProxyManager();
var proxyManager = getDefaultExportFromCjs(proxyManagerExports);
var ProxyManager = _mergeNamespaces({
__proto__: null,
default: proxyManager
}, [ proxyManagerExports ]);
var userObjectExports = requireUserObject();
var userObject = getDefaultExportFromCjs(userObjectExports);
var UO = _mergeNamespaces({
__proto__: null,
default: userObject
}, [ userObjectExports ]);
var padTypes$1 = {
exports: {}
};
var currentVersion = {
exports: {}
};
var hasRequiredCurrentVersion;
function requireCurrentVersion() {
if (hasRequiredCurrentVersion) return currentVersion.exports;
hasRequiredCurrentVersion = 1;
(function(module) {
(() => {
const factory = () => ({
currentVersion: "v7"
});
if (module.exports) {
module.exports = factory();
}
})();
})(currentVersion);
return currentVersion.exports;
}
var hasRequiredPadTypes;
function requirePadTypes() {
if (hasRequiredPadTypes) return padTypes$1.exports;
hasRequiredPadTypes = 1;
(function(module) {
(() => {
const factory = (AppConfig = {}, ApiConfig = {}, OOCurrentVersion) => {
let availablePadTypes = [];
const OO_APPS = [ "sheet", "doc", "presentation" ];
const setCustomize = data => {
AppConfig = data.AppConfig;
ApiConfig = data.ApiConfig;
const ooEnabled = ApiConfig.onlyOffice && ApiConfig.onlyOffice.availableVersions.includes(OOCurrentVersion.currentVersion);
availablePadTypes = AppConfig.availablePadTypes.filter((t => ooEnabled || !OO_APPS.includes(t)));
};
if (Object.keys(AppConfig).length) {
setCustomize({
AppConfig,
ApiConfig
});
}
const Types = {
setCustomize
};
Types.__defineGetter__("availableTypes", (function() {
if (ApiConfig.appsToDisable) {
return availablePadTypes.filter((value => !ApiConfig.appsToDisable.includes(value)));
}
return availablePadTypes;
}));
Types.__defineGetter__("appsToSelect", (function() {
return availablePadTypes.filter((value => ![ "drive", "teams", "file", "contacts", "convert" ].includes(value)));
}));
Types.isAvailable = type => Array.isArray(Types.availableTypes) && Types.availableTypes.includes(type);
return Types;
};
if (module.exports) {
module.exports = factory(undefined, undefined, requireCurrentVersion());
}
})();
})(padTypes$1);
return padTypes$1.exports;
}
var padTypesExports = requirePadTypes();
var padTypes = getDefaultExportFromCjs(padTypesExports);
var PadTypes = _mergeNamespaces({
__proto__: null,
default: padTypes
}, [ padTypesExports ]);
var loginBlock$1 = {
exports: {}
};
var httpCommand = {
exports: {}
};
var hasRequiredHttpCommand;
function requireHttpCommand() {
if (hasRequiredHttpCommand) return httpCommand.exports;
hasRequiredHttpCommand = 1;
(function(module) {
(() => {
const factory = (nThen, Util, ApiConfig = {}, Nacl) => {
const getApiOrigin = function() {
if (!Object.keys(ApiConfig).length) {
return;
}
var url;
var unsafeOriginURL = new URL(ApiConfig.httpUnsafeOrigin);
try {
url = new URL(ApiConfig.websocketPath, ApiConfig.httpUnsafeOrigin);
url.protocol = unsafeOriginURL.protocol;
return url.origin;
} catch (err) {
console.error(err);
return ApiConfig.httpUnsafeOrigin;
}
};
var API_ORIGIN = getApiOrigin();
const setCustomize = data => {
ApiConfig = data.ApiConfig;
API_ORIGIN = getApiOrigin();
};
var clone = o => JSON.parse(JSON.stringify(o));
var randomToken = () => Nacl.util.encodeBase64(Nacl.randomBytes(24));
var postData = function(url, data, cb) {
var CB = Util.once(Util.mkAsync(cb));
fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
}).then((response => {
if (response.ok) {
return void response.text().then((result => {
CB(void 0, Util.tryParse(result));
}));
}
response.json().then().then((result => {
CB(response.status, result);
}));
})).catch((error => {
CB(error);
}));
};
var serverCommand = function(keypair, my_data, cb) {
var obj = clone(my_data);
obj.publicKey = Nacl.util.encodeBase64(keypair.publicKey);
obj.nonce = randomToken();
var href = new URL("/api/auth/", API_ORIGIN);
var txid, date;
nThen((function(w) {
postData(href, obj, w(((err, data) => {
if (err) {
w.abort();
console.error(err);
if (data) {
console.error(data);
}
return void cb(err);
}
if (!data.date || !data.txid) {
w.abort();
return void cb("REQUEST_REJECTED");
}
txid = data.txid;
date = data.date;
})));
})).nThen((function(w) {
var copy = clone(obj);
copy.txid = txid;
copy.date = date;
var toSign = Nacl.util.decodeUTF8(JSON.stringify(copy));
var sig = Nacl.sign.detached(toSign, keypair.secretKey);
var encoded = Nacl.util.encodeBase64(sig);
var obj2 = {
sig: encoded,
txid
};
postData(href, obj2, w(((err, data) => {
if (err) {
w.abort();
console.error(err);
if (data) {
console.error(data);
}
return void cb("RESPONSE_REJECTED", data);
}
cb(void 0, data);
})));
}));
};
serverCommand.setCustomize = setCustomize;
return serverCommand;
};
if (module.exports) {
module.exports = factory(requireNthen(), requireCommonUtil(), undefined, requireNaclFast());
}
})();
})(httpCommand);
return httpCommand.exports;
}
var hasRequiredLoginBlock;
function requireLoginBlock() {
if (hasRequiredLoginBlock) return loginBlock$1.exports;
hasRequiredLoginBlock = 1;
(function(module) {
(() => {
const factory = (Util, ApiConfig = {}, ServerCommand, Nacl) => {
var Block = {};
Block.setCustomize = data => {
ApiConfig = data.ApiConfig;
ServerCommand.setCustomize(data);
};
Block.join = Util.uint8ArrayJoin;
Block.seed = function() {
return Nacl.hash(Nacl.util.decodeUTF8("pewpewpew"));
};
Block.genkeys = function(seed) {
if (!(seed instanceof Uint8Array)) {
throw new Error("INVALID_SEED_FORMAT");
}
if (!seed || typeof seed.length !== "number" || seed.length < 64) {
throw new Error("INVALID_SEED_LENGTH");
}
var signSeed = seed.subarray(0, Nacl.sign.seedLength);
var symmetric = seed.subarray(Nacl.sign.seedLength, Nacl.sign.seedLength + Nacl.secretbox.keyLength);
return {
sign: Nacl.sign.keyPair.fromSeed(signSeed),
symmetric
};
};
Block.keysToRPCFormat = function(keys) {
try {
var sign = keys.sign;
return {
edPrivate: Nacl.util.encodeBase64(sign.secretKey),
edPublic: Nacl.util.encodeBase64(sign.publicKey)
};
} catch (err) {
console.error(err);
return;
}
};
Block.encrypt = function(version, content, keys) {
var u8 = Nacl.util.decodeUTF8(content);
var nonce = Nacl.randomBytes(Nacl.secretbox.nonceLength);
return Block.join([ [ 0 ], nonce, Nacl.secretbox(u8, nonce, keys.symmetric) ]);
};
Block.decrypt = function(u8_content, keys) {
var nonce = u8_content.subarray(1, 1 + Nacl.secretbox.nonceLength);
var box = u8_content.subarray(1 + Nacl.secretbox.nonceLength);
var plaintext = Nacl.secretbox.open(box, nonce, keys.symmetric);
try {
return JSON.parse(Nacl.util.encodeUTF8(plaintext));
} catch (e) {
console.error(e);
return;
}
};
Block.sign = function(ciphertext, keys) {
return Nacl.sign.detached(Nacl.hash(ciphertext), keys.sign.secretKey);
};
Block.serialize = function(content, keys) {
var ciphertext = Block.encrypt(0, content, keys);
var sig = Block.sign(ciphertext, keys);
return {
publicKey: Nacl.util.encodeBase64(keys.sign.publicKey),
signature: Nacl.util.encodeBase64(sig),
ciphertext: Nacl.util.encodeBase64(ciphertext)
};
};
Block.proveAncestor = function(O) {
var u8_pub = Util.find(O, [ "sign", "publicKey" ]);
var u8_secret = Util.find(O, [ "sign", "secretKey" ]);
try {
var u8_sig = Nacl.sign.detached(u8_pub, u8_secret);
return JSON.stringify([ u8_pub, u8_sig ].map(Nacl.util.encodeBase64));
} catch (err) {
return void console.error(err);
}
};
var urlSafeB64 = function(u8) {
return Nacl.util.encodeBase64(u8).replace(/\//g, "-");
};
Block.getBlockUrl = function(keys) {
var publicKey = urlSafeB64(keys.sign.publicKey);
return (ApiConfig.fileHost || ApiConfig.httpUnsafeOrigin || window.location.origin) + "/block/" + publicKey.slice(0, 2) + "/" + publicKey;
};
Block.getBlockHash = function(keys) {
var absolute = Block.getBlockUrl(keys);
var symmetric = urlSafeB64(keys.symmetric);
return absolute + "#" + symmetric;
};
var decodeSafeB64 = function(b64) {
try {
return Nacl.util.decodeBase64(b64.replace(/\-/g, "/"));
} catch (e) {
console.error(e);
return;
}
};
Block.parseBlockHash = function(hash) {
if (typeof hash !== "string") {
return;
}
var parts = hash.split("#");
if (parts.length !== 2) {
return;
}
try {
return {
href: parts[0],
keys: {
symmetric: decodeSafeB64(parts[1])
}
};
} catch (e) {
console.error(e);
return;
}
};
Block.checkRights = function(data, _cb) {
const cb = Util.mkAsync(_cb);
const {blockKeys, auth} = data;
var command = "MFA_CHECK";
if (auth && auth.type) {
command = `${auth.type.toUpperCase()}_` + command;
}
ServerCommand(blockKeys.sign, {
command,
auth: auth && auth.data
}, cb);
};
Block.writeLoginBlock = function(data, cb) {
const {content, blockKeys, oldBlockKeys, auth, pw, session, token, userData} = data;
var command = "WRITE_BLOCK";
if (auth && auth.type) {
command = `${auth.type.toUpperCase()}_` + command;
}
var block = Block.serialize(JSON.stringify(content), blockKeys);
block.auth = auth && auth.data;
block.hasPassword = pw;
block.registrationProof = oldBlockKeys && Block.proveAncestor(oldBlockKeys);
if (token) {
block.inviteToken = token;
}
if (userData) {
block.userData = userData;
}
ServerCommand(blockKeys.sign, {
command,
content: block,
session
}, cb);
};
Block.removeLoginBlock = function(data, cb) {
const {reason, blockKeys, auth, edPublic} = data;
var command = "REMOVE_BLOCK";
if (auth && auth.type) {
command = `${auth.type.toUpperCase()}_` + command;
}
ServerCommand(blockKeys.sign, {
command,
auth: auth && auth.data,
edPublic,
reason
}, cb);
};
Block.updateSSOBlock = function(data, cb) {
const {blockKeys, oldBlockKeys} = data;
var oldProof = oldBlockKeys && Block.proveAncestor(oldBlockKeys);
ServerCommand(blockKeys.sign, {
command: "SSO_UPDATE_BLOCK",
ancestorProof: oldProof
}, cb);
};
return Block;
};
if (module.exports) {
module.exports = factory(requireCommonUtil(), undefined, requireHttpCommand(), requireNaclFast());
}
})();
})(loginBlock$1);
return loginBlock$1.exports;
}
var loginBlockExports = requireLoginBlock();
var loginBlock = getDefaultExportFromCjs(loginBlockExports);
var LoginBlock = _mergeNamespaces({
__proto__: null,
default: loginBlock
}, [ loginBlockExports ]);
var asyncStore$1 = {
exports: {}
};
var JSON_sortify = {
exports: {}
};
var hasRequiredJSON_sortify;
function requireJSON_sortify() {
if (hasRequiredJSON_sortify) return JSON_sortify.exports;
hasRequiredJSON_sortify = 1;
(function(module) {
(function(a) {
module.exports ? module.exports = a() : JSON.sortify = a();
})((function() {
var a = function(b) {
if (Array.isArray(b)) return b.map(a);
if (b instanceof Object) {
var c = [], d = [];
return Object.keys(b).forEach((function(a) {
/^(0|[1-9][0-9]*)$/.test(a) ? c.push(+a) : d.push(a);
})), c.sort((function(c, a) {
return c - a;
})).concat(d.sort()).reduce((function(c, d) {
return c[d] = a(b[d]), c;
}), {});
}
return b;
}, b = JSON.stringify.bind(JSON);
return function sortify(c, d, e) {
var f = b(c, d, 0);
if (!f || f[0] !== "{" && f[0] !== "[") return f;
var g = JSON.parse(f);
return b(a(g), null, e);
};
}));
})(JSON_sortify);
return JSON_sortify.exports;
}
var migrateUserObject$1 = {
exports: {}
};
var commonMessaging = {
exports: {}
};
var hasRequiredCommonMessaging;
function requireCommonMessaging() {
if (hasRequiredCommonMessaging) return commonMessaging.exports;
hasRequiredCommonMessaging = 1;
(function(module) {
(() => {
const factory = (Crypto, Hash, Util, Constants, Realtime) => {
var Msg = {};
var createData = Msg.createData = function(proxy, hash) {
var data = {
channel: hash || Hash.createChannelId(),
displayName: proxy["cryptpad.username"],
profile: proxy.profile && proxy.profile.view,
edPublic: proxy.edPublic,
curvePublic: proxy.curvePublic,
notifications: Util.find(proxy, [ "mailboxes", "notifications", "channel" ]),
avatar: proxy.profile && proxy.profile.avatar,
uid: proxy.uid
};
if (hash === false) {
delete data.channel;
}
return data;
};
var getFriend = Msg.getFriend = function(proxy, pubkey) {
if (!pubkey) {
return;
}
if (pubkey === proxy.curvePublic) {
var data = createData(proxy);
delete data.channel;
return data;
}
return proxy.friends ? proxy.friends[pubkey] : undefined;
};
var getFriendList = Msg.getFriendList = function(proxy) {
if (!proxy.friends) {
proxy.friends = {};
}
return proxy.friends;
};
var eachFriend = function(friends, cb) {
Object.keys(friends).forEach((function(id) {
if (id === "me") {
return;
}
cb(friends[id], id, friends);
}));
};
Msg.getFriendChannelsList = function(proxy) {
var list = [];
eachFriend(proxy.friends, (function(friend) {
list.push(friend.channel);
}));
return list;
};
Msg.declineFriendRequest = function(store, data, cb) {
store.mailbox.sendTo("DECLINE_FRIEND_REQUEST", {}, {
channel: data.notifications,
curvePublic: data.curvePublic
}, (function(obj) {
cb(obj);
}));
};
Msg.acceptFriendRequest = function(store, data, cb) {
var friend = getFriend(store.proxy, data.curvePublic) || {};
var myData = createData(store.proxy, friend.channel || data.channel);
store.mailbox.sendTo("ACCEPT_FRIEND_REQUEST", {
user: myData
}, {
channel: data.notifications,
curvePublic: data.curvePublic
}, (function(obj) {
cb(obj);
}));
};
Msg.addToFriendList = function(cfg, data, cb) {
var proxy = cfg.proxy;
var friends = getFriendList(proxy);
var pubKey = data.curvePublic;
if (pubKey === proxy.curvePublic) {
return void cb("E_MYKEY");
}
friends[pubKey] = data;
Realtime.whenRealtimeSyncs(cfg.realtime, (function() {
cb();
cfg.pinPads([ data.channel ], (function(res) {
if (res.error) {
console.error(res.error);
}
}));
}));
};
Msg.updateMyData = function(store, curve) {
var myData = createData(store.proxy, false);
if (store.proxy.friends) {
store.proxy.friends.me = Util.clone(myData);
delete store.proxy.friends.me.channel;
}
if (store.modules["team"]) {
store.modules["team"].updateMyData(myData);
}
var todo = function(friend) {
if (!friend || !friend.notifications) {
return;
}
delete friend.user;
myData.channel = friend.channel;
store.mailbox.sendTo("UPDATE_DATA", myData, {
channel: friend.notifications,
curvePublic: friend.curvePublic
}, (function(obj) {
if (obj && obj.error) {
console.error(obj);
}
}));
};
if (curve) {
var friend = getFriend(store.proxy, curve);
return void todo(friend);
}
eachFriend(store.proxy.friends || {}, todo);
};
Msg.removeFriend = function(store, curvePublic, cb) {
var proxy = store.proxy;
var friend = proxy.friends[curvePublic];
if (!friend) {
return void cb({
error: "ENOENT"
});
}
if (!friend.notifications) {
return void cb({
error: "EINVAL"
});
}
store.mailbox.sendTo("UNFRIEND", {
curvePublic: proxy.curvePublic
}, {
channel: friend.notifications,
curvePublic: friend.curvePublic
}, (function(obj) {
if (obj && obj.error) {
return void cb(obj);
}
store.messenger.onFriendRemoved(curvePublic, friend.channel);
delete proxy.friends[curvePublic];
Realtime.whenRealtimeSyncs(store.realtime, (function() {
cb(obj);
}));
}));
};
return Msg;
};
if (module.exports) {
module.exports = factory(requireCrypto(), requireCommonHash(), requireCommonUtil(), requireCommonConstants(), requireCommonRealtime());
}
})();
})(commonMessaging);
return commonMessaging.exports;
}
var cryptget = {
exports: {}
};
var pinpad = {
exports: {}
};
var rpc = {
exports: {}
};
var hasRequiredRpc;
function requireRpc() {
if (hasRequiredRpc) return rpc.exports;
hasRequiredRpc = 1;
(function(module) {
(function() {
var factory = function(Util, Nacl) {
var uid = Util.uid;
var tryParse = Util.tryParse;
var signMsg = function(data, signKey) {
var buffer = Nacl.util.decodeUTF8(JSON.stringify(data));
return Nacl.util.encodeBase64(Nacl.sign.detached(buffer, signKey));
};
var sendMsg = function(ctx, data, cb) {
if (typeof cb !== "function") {
throw new Error("expected callback");
}
var network = ctx.network;
var hkn = network.historyKeeper;
if (typeof hkn !== "string") {
return void cb("NO_HISTORY_KEEPER");
}
var txid = uid();
var pending = ctx.pending[txid] = function(err, response) {
cb(err, response);
};
pending.data = data;
pending.called = 0;
return network.sendto(hkn, JSON.stringify([ txid, data ]));
};
var matchesAnon = function(ctx, txid) {
if (!ctx.anon) {
return false;
}
if (typeof ctx.anon.pending[txid] !== "function") {
return false;
}
return true;
};
var handleAnon = function(ctx, txid, body) {
var pending = ctx.pending[txid];
if (body[0] === "ERROR") {
pending(body[1]);
} else {
pending(void 0, body.slice(1));
}
delete ctx.pending[txid];
};
var onMsg = function(ctx, msg) {
if (typeof msg !== "string") {
console.error("received non-string message [%s]", msg);
}
var parsed = tryParse(msg);
if (!parsed) {
return void console.error(new Error("could not parse message: %s", msg));
}
if (!Array.isArray(parsed)) {
return;
}
if (/(FULL_HISTORY|HISTORY_RANGE)/.test(parsed[0])) {
return;
}
var txid = parsed[0];
if (typeof txid !== "string") {
return;
}
if (matchesAnon(ctx, txid)) {
return void handleAnon(ctx.anon, txid, parsed.slice(1));
}
if (ctx.authenticated.some((function(rpc_ctx) {
var pending = rpc_ctx.pending[txid];
if (typeof pending !== "function") {
return false;
}
if (parsed[1] !== "ERROR") {
if (/\|/.test(parsed[1]) && rpc_ctx.cookie !== parsed[1]) {
rpc_ctx.cookie = parsed[1];
}
pending(void 0, parsed.slice(2));
delete rpc_ctx.pending[txid];
return true;
}
if (parsed[2] === "NO_COOKIE") {
rpc_ctx.send("COOKIE", "", (function(e) {
if (e) {
console.error(e);
return void pending(e);
}
if (rpc_ctx.resend(txid)) {
delete rpc_ctx.pending[txid];
}
}));
return true;
}
pending(parsed[2]);
delete rpc_ctx.pending[txid];
return true;
}))) {
return;
}
console.error("UNHANDLED RPC MESSAGE", msg);
};
var networks = [];
var contexts = [];
var initNetworkContext = function(network) {
var ctx = {
network,
connected: true,
anon: undefined,
authenticated: []
};
networks.push(network);
contexts.push(ctx);
network.on("message", (function(msg, sender) {
if (sender !== network.historyKeeper) {
return;
}
onMsg(ctx, msg);
}));
network.on("disconnect", (function() {
ctx.connected = false;
if (ctx.anon) {
ctx.anon.connected = false;
}
ctx.authenticated.forEach((function(ctx) {
ctx.connected = false;
}));
}));
network.on("reconnect", (function() {
if (ctx.anon) {
ctx.anon.connected = true;
}
ctx.authenticated.forEach((function(ctx) {
ctx.connected = true;
}));
}));
return ctx;
};
var getNetworkContext = function(network) {
var i;
networks.some((function(current, j) {
if (network !== current) {
return false;
}
i = j;
return true;
}));
if (contexts[i]) {
return contexts[i];
}
return initNetworkContext(network);
};
var initAuthenticatedRpc = function(networkContext, keys) {
var ctx = {
network: networkContext.network,
publicKey: keys.publicKeyString,
timeouts: {},
pending: {},
cookie: null,
connected: true
};
var send = ctx.send = function(type, msg, _cb) {
var cb = Util.mkAsync(_cb);
if (!ctx.connected && type !== "COOKIE") {
return void cb("DISCONNECTED");
}
var data = [ type, msg ];
if (ctx.cookie && ctx.cookie.join) {
data.unshift(ctx.cookie.join("|"));
} else {
data.unshift(ctx.cookie);
}
var sig = signMsg(data, keys.signKey);
data.unshift(keys.publicKeyString);
data.unshift(sig);
return sendMsg(ctx, data, cb);
};
ctx.resend = function(txid) {
var pending = ctx.pending[txid];
if (pending.called) {
console.error("[%s] called too many times", txid);
return true;
}
pending.called++;
pending.data[2] = ctx.cookie;
pending.data[0] = signMsg(pending.data.slice(2), keys.signKey);
var new_txid = uid();
ctx.pending[new_txid] = pending;
delete ctx.pending[txid];
try {
return ctx.network.sendto(ctx.network.historyKeeper, JSON.stringify([ new_txid, pending.data ]));
} catch (e) {
console.log("failed to resend");
console.error(e);
}
};
send.unauthenticated = function(type, msg, _cb) {
var cb = Util.mkAsync(_cb);
if (!ctx.connected) {
return void cb("DISCONNECTED");
}
var data = [ null, keys.publicKeyString, null, type, msg ];
if (ctx.cookie && ctx.cookie.join) {
data[2] = ctx.cookie.join("|");
} else {
data[2] = ctx.cookie;
}
return sendMsg(ctx, data, cb);
};
ctx.destroy = function() {
Object.keys(ctx.timeouts).forEach((function(to) {
clearTimeout(to);
}));
var idx = networkContext.authenticated.indexOf(ctx);
if (idx === -1) {
return;
}
networkContext.authenticated.splice(idx, 1);
};
networkContext.authenticated.push(ctx);
return ctx;
};
var getAuthenticatedContext = function(networkContext, keys) {
if (!networkContext) {
throw new Error("expected network context");
}
var publicKey = keys.publicKeyString;
var i;
networkContext.authenticated.some((function(ctx, j) {
if (ctx.publicKey !== publicKey) {
return false;
}
i = j;
return true;
}));
if (networkContext.authenticated[i]) {
return networkContext.authenticated[i];
}
return initAuthenticatedRpc(networkContext, keys);
};
var create = function(network, edPrivateKey, edPublicKey, _cb) {
if (typeof _cb !== "function") {
throw new Error("expected callback");
}
var cb = Util.mkAsync(_cb);
var signKey;
try {
signKey = Nacl.util.decodeBase64(edPrivateKey);
if (signKey.length !== 64) {
throw new Error("private key did not match expected length of 64");
}
} catch (err) {
return void cb(err);
}
try {
if (Nacl.util.decodeBase64(edPublicKey).length !== 32) {
return void cb("expected public key to be 32 uint");
}
} catch (err) {
return void cb(err);
}
if (!network) {
return void cb("NO_NETWORK");
}
var net_ctx = getNetworkContext(network);
var rpc_ctx = getAuthenticatedContext(net_ctx, {
publicKeyString: edPublicKey,
signKey
});
rpc_ctx.send("COOKIE", "", (function(e) {
if (e) {
return void cb(e);
}
cb(void 0, {
send: rpc_ctx.send,
destroy: rpc_ctx.destroy
});
}));
};
var initAnonRpc = function(networkContext) {
var ctx = {
network: networkContext.network,
timeouts: {},
pending: {},
connected: true
};
networkContext.anon = ctx;
ctx.send = function(type, msg, _cb) {
var cb = Util.mkAsync(_cb);
if (!ctx.connected) {
return void cb("DISCONNECTED");
}
var data = [ type, msg ];
return sendMsg(ctx, data, cb);
};
ctx.resend = function(txid) {
var pending = ctx.pending[txid];
if (pending.called) {
console.error("[%s] called too many times", txid);
return true;
}
pending.called++;
try {
return ctx.network.sendto(ctx.network.historyKeeper, JSON.stringify([ txid, pending.data ]));
} catch (e) {
console.log("failed to resend");
console.error(e);
}
};
ctx.destroy = function() {
Object.keys(ctx.timeouts).forEach((function(to) {
clearTimeout(to);
}));
networkContext.anon = undefined;
};
return ctx;
};
var getAnonContext = function(networkContext) {
return networkContext.anon || initAnonRpc(networkContext);
};
var createAnonymous = function(network, _cb) {
var cb = Util.mkAsync(_cb);
if (typeof cb !== "function") {
throw new Error("expected callback");
}
if (!network) {
return void cb("NO_NETWORK");
}
var ctx = getAnonContext(getNetworkContext(network));
cb(void 0, {
send: ctx.send,
destroy: ctx.destroy
});
};
return {
create,
createAnonymous
};
};
if (module.exports) {
module.exports = factory(requireCommonUtil(), requireNaclFast());
}
})();
})(rpc);
return rpc.exports;
}
var hasRequiredPinpad;
function requirePinpad() {
if (hasRequiredPinpad) return pinpad.exports;
hasRequiredPinpad = 1;
(function(module) {
(function() {
var factory = function(Util, Rpc) {
var create = function(network, proxy, _cb, Cache) {
if (typeof _cb !== "function") {
throw new Error("Expected callback");
}
var cb = Util.once(Util.mkAsync(_cb));
if (!network) {
return void cb("INVALID_NETWORK");
}
if (!proxy) {
return void cb("INVALID_PROXY");
}
var edPrivate = proxy.edPrivate;
var edPublic = proxy.edPublic;
if (!(edPrivate && edPublic)) {
return void cb("INVALID_KEYS");
}
Rpc.create(network, edPrivate, edPublic, (function(e, rpc) {
if (e) {
return void cb(e);
}
var exp = {};
exp.destroy = rpc.destroy;
exp.publicKey = edPublic;
exp.send = rpc.send;
exp.pin = function(channels, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
if (!Array.isArray(channels)) {
return void cb("[TypeError] pin expects an array");
}
rpc.send("PIN", channels, cb);
};
exp.unpin = function(channels, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
if (!Array.isArray(channels)) {
return void cb("[TypeError] pin expects an array");
}
rpc.send("UNPIN", channels, cb);
};
exp.adminRpc = function(obj, cb) {
if (!obj.cmd) {
setTimeout((function() {
cb("[TypeError] admin rpc expects a command");
}));
return;
}
var params = [ obj.cmd, obj.data ];
rpc.send("ADMIN", params, cb);
};
exp.getServerHash = function(cb) {
rpc.send("GET_HASH", edPublic, (function(e, hash) {
if (!(hash && hash[0])) {
return void cb("NO_HASH_RETURNED");
}
cb(e, Array.isArray(hash) && hash[0] || undefined);
}));
};
exp.reset = function(channels, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
if (!Array.isArray(channels)) {
return void cb("[TypeError] pin expects an array");
}
rpc.send("RESET", channels, cb);
};
exp.getFileListSize = function(cb) {
rpc.send("GET_TOTAL_SIZE", undefined, (function(e, response) {
if (e) {
return void cb(e);
}
if (response && response.length && typeof response[0] === "number") {
cb(void 0, response[0]);
} else {
cb("INVALID_RESPONSE");
}
}));
};
exp.updatePinLimits = function(cb) {
rpc.send("UPDATE_LIMITS", undefined, (function(e, response) {
if (e) {
return void cb(e);
}
if (response && response.length && typeof response[0] === "number") {
cb(void 0, response[0], response[1], response[2]);
} else {
cb("INVALID_RESPONSE");
}
}));
};
exp.getLimit = function(cb) {
rpc.send("GET_LIMIT", undefined, (function(e, response) {
if (e) {
return void cb(e);
}
if (response && response.length && typeof response[0] === "number") {
cb(void 0, response[0], response[1], response[2]);
} else {
cb("INVALID_RESPONSE");
}
}));
};
exp.trimHistory = function(data, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
if (typeof data !== "object" || !data.channel || !data.hash) {
return void cb("INVALID_ARGUMENTS");
}
rpc.send("TRIM_HISTORY", data, (function(e) {
if (e) {
return cb(e);
}
cb();
}));
};
exp.clearOwnedChannel = function(channel, cb) {
if (typeof channel !== "string" || channel.length !== 32) {
return void cb("INVALID_ARGUMENTS");
}
rpc.send("CLEAR_OWNED_CHANNEL", channel, (function(e) {
if (e) {
return cb(e);
}
cb();
}));
};
exp.removeOwnedChannel = function(channel, cb, reason) {
if (typeof channel !== "string" || [ 32, 48 ].indexOf(channel.length) === -1) {
console.error("invalid channel to remove", channel);
return void cb("INVALID_ARGUMENTS");
}
rpc.send("REMOVE_OWNED_CHANNEL", {
channel,
reason
}, (function(e, response) {
if (e) {
return void cb(e);
}
if (response && response.length && response[0] === "OK") {
cb();
if (Cache && Cache.clearChannel) {
Cache.clearChannel(channel);
}
} else {
cb("INVALID_RESPONSE");
}
}));
};
exp.removePins = function(cb) {
rpc.send("REMOVE_PINS", undefined, (function(e, response) {
if (e) {
return void cb(e);
}
if (response && response.length && response[0] === "OK") {
cb();
} else {
cb("INVALID_RESPONSE");
}
}));
};
exp.uploadComplete = function(id, cb) {
rpc.send("UPLOAD_COMPLETE", id, (function(e, res) {
if (e) {
return void cb(e);
}
var id = res[0];
if (typeof id !== "string") {
return void cb("INVALID_ID");
}
cb(void 0, id);
}));
};
exp.ownedUploadComplete = function(id, cb) {
rpc.send("OWNED_UPLOAD_COMPLETE", id, (function(e, res) {
if (e) {
return void cb(e);
}
var id = res[0];
if (typeof id !== "string") {
return void cb("INVALID_ID");
}
cb(void 0, id);
}));
};
exp.uploadStatus = function(size, cb) {
if (typeof size !== "number") {
return void setTimeout((function() {
cb("INVALID_SIZE");
}));
}
rpc.send("UPLOAD_STATUS", size, (function(e, res) {
if (e) {
return void cb(e);
}
var pending = res[0];
if (typeof pending !== "boolean") {
return void cb("INVALID_RESPONSE");
}
cb(void 0, pending);
}));
};
exp.uploadCancel = function(size, cb) {
rpc.send("UPLOAD_CANCEL", size, (function(e) {
if (e) {
return void cb(e);
}
cb();
}));
};
exp.setMetadata = function(obj, cb) {
rpc.send("SET_METADATA", {
channel: obj.channel,
command: obj.command,
value: obj.value
}, cb);
};
cb(e, exp);
}));
};
return {
create
};
};
if (module.exports) {
module.exports = factory(requireCommonUtil(), requireRpc());
}
})();
})(pinpad);
return pinpad.exports;
}
var hasRequiredCryptget;
function requireCryptget() {
if (hasRequiredCryptget) return cryptget.exports;
hasRequiredCryptget = 1;
(function(module) {
(() => {
const factory = (Crypto, CPNetflux, Netflux, Util, Hash, Realtime, NetConfig, Cache, Pinpad, nThen) => {
var finish = function(S, err, doc) {
if (S.done) {
return;
}
S.cb(err && err.error, doc, err);
S.done = true;
if (!S.hasNetwork) {
var disconnect = Util.find(S, [ "network", "disconnect" ]);
if (typeof disconnect === "function") {
disconnect();
}
}
if (S.realtime && S.realtime.stop) {
try {
S.realtime.stop();
} catch (e) {
console.error(e);
}
}
var abort = Util.find(S, [ "session", "realtime", "abort" ]);
if (typeof abort === "function") {
S.session.realtime.sync();
abort();
}
};
var makeNetwork = function(cb) {
var wsUrl = NetConfig.getWebsocketURL();
Netflux.connect(wsUrl).then((function(network) {
cb(null, network);
}), (function(err) {
cb(err);
}));
};
var start = function(Session, config) {
nThen((function(waitFor) {
if (Session.hasNetwork) {
return;
}
makeNetwork(waitFor((function(err, network) {
if (err) {
return;
}
config.network = network;
})));
})).nThen((function() {
Session.realtime = CPNetflux.start(config);
}));
};
var onRejected = function(config, Session, data, cb) {
if (!Array.isArray(data) || !data.length || data[0].length !== 16) {
return void cb(true);
}
if (!Array.isArray(Session.accessKeys)) {
return void cb(true);
}
config.network.historyKeeper = data[0];
nThen((function(waitFor) {
Session.accessKeys.forEach((function(obj) {
Pinpad.create(config.network, obj, waitFor((function(e) {
console.log("done", obj);
if (e) {
console.error(e);
}
})));
}));
})).nThen((function() {
cb();
}));
};
var makeConfig = function(hash, opt) {
var secret;
if (typeof hash === "string") {
secret = Hash.getSecrets("pad", hash, opt.password);
} else if (typeof hash === "object") {
secret = hash;
}
if (!secret.keys) {
secret.keys = secret.key;
}
var config = {
websocketURL: NetConfig.getWebsocketURL(opt.origin),
channel: secret.channel,
validateKey: secret.keys.validateKey || undefined,
crypto: Crypto.createEncryptor(secret.keys),
logLevel: 0,
initialState: opt.initialState,
Cache
};
return config;
};
var isObject = function(o) {
return typeof o === "object";
};
var overwrite = function(a, b) {
if (!(isObject(a) && isObject(b))) {
return;
}
Object.keys(b).forEach((function(k) {
a[k] = b[k];
}));
};
var get = function(hash, cb, opt, progress) {
if (typeof cb !== "function") {
throw new Error("Cryptget expects a callback");
}
opt = opt || {};
progress = progress || function() {};
var config = makeConfig(hash, opt);
var Session = {
cb,
accessKeys: opt.accessKeys,
hasNetwork: Boolean(opt.network)
};
config.onRejected = function(data, cb) {
onRejected(config, Session, data, cb);
};
config.onReady = function(info) {
var rt = Session.session = info.realtime;
Session.network = info.network;
progress(1);
finish(Session, void 0, rt.getUserDoc());
};
config.onError = function(info) {
console.warn(info);
finish(Session, info);
};
config.onChannelError = function(info) {
console.error(info);
finish(Session, info);
};
config.onCacheReady = opt.onCacheReady;
var i = 0;
config.onMessage = function() {
i++;
progress(Math.min(.99, i / 100));
};
overwrite(config, opt);
start(Session, config);
};
var put = function(hash, doc, cb, opt) {
if (typeof cb !== "function") {
throw new Error("Cryptput expects a callback");
}
opt = opt || {};
var config = makeConfig(hash, opt);
var Session = {
cb,
accessKeys: opt.accessKeys,
hasNetwork: Boolean(opt.network)
};
config.onRejected = function(data, cb) {
onRejected(config, Session, data, cb);
};
config.onReady = function(info) {
var realtime = Session.session = info.realtime;
Session.network = info.network;
realtime.contentUpdate(doc);
var to = setTimeout((function() {
cb(new Error("Timeout"));
}), 15e3);
Realtime.whenRealtimeSyncs(realtime, (function() {
clearTimeout(to);
var doc = realtime.getAuthDoc();
realtime.abort();
finish(Session, void 0, doc);
}));
};
config.onChannelError = function(info) {
finish(Session, info);
};
overwrite(config, opt);
start(Session, config);
};
return {
get,
put
};
};
if (module.exports) {
module.exports = factory(requireCrypto(), requireChainpadNetflux(), requireNetfluxClient(), requireCommonUtil(), requireCommonHash(), requireCommonRealtime(), requireNetworkConfig(), requireCacheStore(), requirePinpad(), requireNthen(), requireChainpad_dist());
}
})();
})(cryptget);
return cryptget.exports;
}
var mailbox$1 = {
exports: {}
};
var notify = {
exports: {}
};
var hasRequiredNotify;
function requireNotify() {
if (hasRequiredNotify) return notify.exports;
hasRequiredNotify = 1;
(function(module) {
(() => {
const factory = (ApiConfig = {}) => {
let window = globalThis;
var Module = {};
ApiConfig.requireConf = ApiConfig.requireConf || {};
Module.setCustomize = data => {
ApiConfig = data.ApiConfig;
};
var apps = [ "code", "slide", "pad", "kanban", "whiteboard", "diagram", "sheet", "poll", "teams", "form", "doc", "presentation" ];
var app = window.location && window.location.pathname.slice(1, -1);
var suffix = apps.indexOf(app) !== -1 ? "-" + app : "";
var DEFAULT_MAIN = "/customize/favicon/main-favicon" + suffix + ".png?" + ApiConfig.requireConf.urlArgs;
var DEFAULT_ALT = "/customize/favicon/alt-favicon" + suffix + ".png?" + ApiConfig.requireConf.urlArgs;
var DEFAULT_MAIN_ICO = "/customize/favicon/main-favicon" + suffix + ".ico?" + ApiConfig.requireConf.urlArgs;
var DEFAULT_ALT_ICO = "/customize/favicon/alt-favicon" + suffix + ".ico?" + ApiConfig.requireConf.urlArgs;
var document = window.document;
var isSupported = Module.isSupported = function() {
return typeof window.Notification === "function" && window.isSecureContext;
};
var hasPermission = Module.hasPermission = function() {
return Notification.permission === "granted";
};
var getPermission = Module.getPermission = function(f) {
f = f || function() {};
if (!Notification || typeof Notification.requestPermission !== "function") {
return void f(false);
}
Notification.requestPermission((function(permission) {
if (permission === "granted") {
f(true);
} else {
f(false);
}
}));
};
var create = Module.create = function(msg, title, icon) {
if (document && !icon) {
var favicon = document.getElementById("favicon");
icon = favicon.getAttribute("data-main-favicon") || DEFAULT_ALT;
} else if (!icon) {
icon = DEFAULT_ALT;
}
var n = new Notification(title, {
icon,
body: msg
});
n.onclick = function() {
if (!document) {
return;
}
try {
parent.focus();
window.focus();
this.close();
} catch (e) {}
};
return n;
};
Module.system = function(msg, title, icon) {
if (!isSupported()) {
return;
} else if (hasPermission()) {
return create(msg, title, icon);
} else if (Notification.permission !== "denied") {
getPermission((function(state) {
if (state) {
create(msg, title, icon);
}
}));
}
};
var createFavicon = function() {
if (!document) {
return void console.error("document is not available in this context");
}
console.debug("creating favicon");
var attrs = {
id: "favicon",
type: "image/png",
rel: "icon",
"data-main-favicon": DEFAULT_MAIN,
"data-alt-favicon": DEFAULT_ALT,
href: DEFAULT_MAIN
};
if (!document.getElementById("favicon")) {
var fav = document.createElement("link");
Object.keys(attrs).forEach((function(k) {
fav.setAttribute(k, attrs[k]);
}));
document.head.appendChild(fav);
}
if (!document.getElementById("favicon-ico")) {
var faviconLink = document.createElement("link");
attrs.href = attrs.href.replace(/\.png/g, ".ico");
attrs.id = "favicon-ico";
attrs.type = "image/x-icon";
Object.keys(attrs).forEach((function(k) {
faviconLink.setAttribute(k, attrs[k]);
}));
document.head.appendChild(faviconLink);
}
};
if (document && !document.getElementById("favicon")) {
createFavicon();
}
Module.tab = function(frequency, count) {
if (!document) {
return void console.error("document is not available in this context");
}
var key = "_pendingTabNotification";
var favicon = document.getElementById("favicon");
var faviconIco = document.getElementById("favicon-ico");
var main = DEFAULT_MAIN;
var alt = DEFAULT_ALT;
var mainIco = DEFAULT_MAIN_ICO;
var altIco = DEFAULT_ALT_ICO;
if (favicon) {
main = favicon.getAttribute("data-main-favicon") || DEFAULT_MAIN;
alt = favicon.getAttribute("data-alt-favicon") || DEFAULT_ALT;
favicon.setAttribute("href", main);
}
if (faviconIco) {
mainIco = faviconIco.getAttribute("data-main-favicon") || DEFAULT_MAIN_ICO;
altIco = faviconIco.getAttribute("data-alt-favicon") || DEFAULT_ALT_ICO;
faviconIco.setAttribute("href", mainIco);
}
var cancel = function(pending) {
if (Module[key]) {
window.clearInterval(Module[key]);
if (favicon) {
favicon.setAttribute("href", pending ? alt : main);
}
if (faviconIco) {
faviconIco.setAttribute("href", pending ? altIco : mainIco);
}
return true;
}
return false;
};
cancel();
var step = function() {
if (favicon) {
favicon.setAttribute("href", favicon.getAttribute("href") === main ? alt : main);
}
if (faviconIco) {
faviconIco.setAttribute("href", faviconIco.getAttribute("href") === mainIco ? altIco : mainIco);
}
--count;
};
Module[key] = window.setInterval((function() {
if (count > 0) {
return step();
}
cancel(true);
}), frequency);
step();
return {
cancel
};
};
return Module;
};
if (module.exports) {
module.exports = factory(undefined);
}
})();
})(notify);
return notify.exports;
}
var mailboxHandlers = {
exports: {}
};
var hasRequiredMailboxHandlers;
function requireMailboxHandlers() {
if (hasRequiredMailboxHandlers) return mailboxHandlers.exports;
hasRequiredMailboxHandlers = 1;
(function(module) {
(() => {
const factory = (Messaging, Hash, Util, Crypto, Block) => {
var getRandomTimeout = function(ctx) {
var lag = ctx.store.realtime.getLag().lag || 0;
return (Math.max(0, lag) + 300) * 20 * (.5 + Math.random());
};
var handlers = {};
var removeHandlers = {};
var isMuted = function(ctx, data) {
var muted = ctx.store.proxy.mutedUsers || {};
var curvePublic = Util.find(data, [ "msg", "author" ]);
if (!curvePublic) {
return false;
}
return Boolean(muted[curvePublic]);
};
var isChannelMuted = function(ctx, channel) {
var muted = ctx.store.proxy.mutedChannels || [];
return muted.includes(channel);
};
var friendRequest = {};
handlers["FRIEND_REQUEST"] = function(ctx, box, data, cb) {
var userData = data.msg.content.user || data.msg.content;
if (isMuted(ctx, data)) {
return void cb(true);
}
if (friendRequest[data.msg.author]) {
return void cb(true);
}
friendRequest[data.msg.author] = {
type: box.type,
hash: data.hash
};
if (Messaging.getFriend(ctx.store.proxy, data.msg.author) || ctx.store.proxy.friends_pending[data.msg.author]) {
delete ctx.store.proxy.friends_pending[data.msg.author];
Messaging.acceptFriendRequest(ctx.store, userData, (function(obj) {
if (obj && obj.error) {
return void cb();
}
Messaging.addToFriendList({
proxy: ctx.store.proxy,
realtime: ctx.store.realtime,
pinPads: ctx.pinPads
}, userData, (function(err) {
if (err) {
console.error(err);
return void cb(true);
}
if (ctx.store.messenger) {
ctx.store.messenger.onFriendAdded(userData);
}
ctx.updateMetadata();
cb(true);
}));
}));
return;
}
cb();
};
removeHandlers["FRIEND_REQUEST"] = function(ctx, box, data) {
var userData = data.content.user || data.content;
if (friendRequest[userData.curvePublic]) {
delete friendRequest[userData.curvePublic];
}
};
var friendRequestDeclined = {};
var friendRequestAccepted = {};
handlers["DECLINE_FRIEND_REQUEST"] = function(ctx, box, data, cb) {
var userData = data.msg.content.user || data.msg.content;
if (!userData.curvePublic) {
userData.curvePublic = data.msg.author;
}
setTimeout((function() {
cb(true);
if (!ctx.store.proxy.friends_pending[data.msg.author]) {
return;
}
delete ctx.store.proxy.friends_pending[data.msg.author];
ctx.updateMetadata();
if (friendRequestDeclined[data.msg.author]) {
return;
}
box.sendMessage({
type: "FRIEND_REQUEST_DECLINED",
content: {
user: userData
}
}, (function(hash) {
friendRequestDeclined[data.msg.author] = {
type: box.type,
hash
};
}));
}), getRandomTimeout(ctx));
};
handlers["FRIEND_REQUEST_DECLINED"] = function(ctx, box, data, cb) {
ctx.updateMetadata();
var curve = data.msg.content.user.curvePublic || data.msg.content.user;
var toRemove = friendRequestAccepted[curve];
delete friendRequestAccepted[curve];
if (friendRequestDeclined[curve]) {
return void cb(true, toRemove);
}
friendRequestDeclined[curve] = {
type: box.type,
hash: data.hash
};
cb(false, toRemove);
};
removeHandlers["FRIEND_REQUEST_DECLINED"] = function(ctx, box, data) {
var curve = data.content.user.curvePublic || data.content.user;
if (friendRequestDeclined[curve]) {
delete friendRequestDeclined[curve];
}
};
handlers["ACCEPT_FRIEND_REQUEST"] = function(ctx, box, data, cb) {
var userData = data.msg.content.user || data.msg.content;
setTimeout((function() {
cb(true);
if (!ctx.store.proxy.friends_pending[data.msg.author]) {
return;
}
delete ctx.store.proxy.friends_pending[data.msg.author];
Messaging.addToFriendList({
proxy: ctx.store.proxy,
realtime: ctx.store.realtime,
pinPads: ctx.pinPads
}, userData, (function(err) {
if (err) {
return void console.error(err);
}
if (ctx.store.messenger) {
ctx.store.messenger.onFriendAdded(userData);
}
ctx.updateMetadata();
if (ctx.store.modules["profile"]) {
ctx.store.modules["profile"].update();
}
if (friendRequestAccepted[data.msg.author]) {
return;
}
box.sendMessage({
type: "FRIEND_REQUEST_ACCEPTED",
content: {
user: userData
}
}, (function(hash) {
friendRequestAccepted[data.msg.author] = {
type: box.type,
hash
};
}));
}));
}), getRandomTimeout(ctx));
};
handlers["FRIEND_REQUEST_ACCEPTED"] = function(ctx, box, data, cb) {
ctx.updateMetadata();
var curve = data.msg.content.user.curvePublic || data.msg.content.user;
var toRemove = friendRequestDeclined[curve];
delete friendRequestDeclined[curve];
if (friendRequestAccepted[curve]) {
return void cb(true, toRemove);
}
friendRequestAccepted[curve] = {
type: box.type,
hash: data.hash
};
cb(false, toRemove);
};
removeHandlers["FRIEND_REQUEST_ACCEPTED"] = function(ctx, box, data) {
var curve = data.content.user.curvePublic || data.content.user;
if (friendRequestAccepted[curve]) {
delete friendRequestAccepted[curve];
}
};
handlers["CANCEL_FRIEND_REQUEST"] = function(ctx, box, data, cb) {
var f = friendRequest[data.msg.author];
if (!f) {
return void cb(true);
}
cb(true, f);
};
handlers["UNFRIEND"] = function(ctx, box, data, cb) {
var curve = data.msg.author;
var friend = Messaging.getFriend(ctx.store.proxy, curve);
if (!friend) {
return void cb(true);
}
delete ctx.store.proxy.friends[curve];
delete ctx.store.proxy.friends_pending[curve];
if (ctx.store.messenger) {
ctx.store.messenger.onFriendRemoved(curve, friend.channel);
}
ctx.updateMetadata();
cb(true);
};
handlers["UPDATE_DATA"] = function(ctx, box, data, cb) {
var msg = data.msg;
var curve = msg.author;
var friend = ctx.store.proxy.friends && ctx.store.proxy.friends[curve];
if (!friend || typeof msg.content !== "object") {
return void cb(true);
}
Object.keys(msg.content).forEach((function(key) {
friend[key] = msg.content[key];
}));
if (ctx.store.messenger) {
ctx.store.messenger.onFriendUpdate(curve);
}
ctx.updateMetadata();
cb(true);
};
var encryptPassword = function(ctx, password) {
let uHash = ctx.store.data.blockHash;
let uSecret = Block.parseBlockHash(uHash);
let key = uSecret.keys.symmetric;
return Crypto.encrypt(password, key);
};
var channels = {};
handlers["SHARE_PAD"] = function(ctx, box, data, cb) {
var msg = data.msg;
var hash = data.hash;
var content = msg.content;
if (isMuted(ctx, data)) {
return void cb(true);
}
var channel = content.isStatic ? content.href : Hash.hrefToHexChannelId(content.href, content.password);
var parsed = Hash.parsePadUrl(content.href);
var mode = parsed.hashData && parsed.hashData.mode || "n/a";
var old = channels[channel];
var toRemove;
if (old) {
if (old.mode === "edit" && mode === "view") {
return void cb(true);
}
toRemove = old.data;
}
if (content.password) {
content.password = encryptPassword(ctx, content.password);
}
channels[channel] = {
mode,
data: {
type: box.type,
hash
}
};
cb(false, toRemove);
};
removeHandlers["SHARE_PAD"] = function(ctx, box, data, hash) {
var content = data.content;
var channel = Hash.hrefToHexChannelId(content.href, content.password);
var old = channels[channel];
if (old && old.data && old.data.hash === hash) {
delete channels[channel];
}
};
var supportMessage = false;
handlers["SUPPORT_MESSAGE"] = function(ctx, box, data, cb) {
if (supportMessage) {
return void cb(true);
}
supportMessage = true;
cb();
};
removeHandlers["SUPPORT_MESSAGE"] = function() {
supportMessage = false;
};
handlers["REQUEST_PAD_ACCESS"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
if (isMuted(ctx, data)) {
return void cb(true);
}
var channel = content.channel;
var res = ctx.store.manager.findChannel(channel);
if (!res.length) {
return void cb(true);
}
var edPublic = ctx.store.proxy.edPublic;
var title, href;
if (!res.some((function(obj) {
if (obj.data && Array.isArray(obj.data.owners) && obj.data.owners.indexOf(edPublic) !== -1 && obj.data.href) {
href = obj.data.href;
title = obj.data.filename || obj.data.title;
return true;
}
}))) {
return void cb(true);
}
content.title = title;
content.href = href;
cb(false);
};
handlers["GIVE_PAD_ACCESS"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
var channel = content.channel;
var res = ctx.store.manager.findChannel(channel, true);
var title;
res.forEach((function(obj) {
if (obj.data && !obj.data.href) {
if (!title) {
title = obj.data.filename || obj.data.title;
}
obj.userObject.setHref(channel, null, content.href);
}
}));
content.title = title || content.title;
cb(false);
};
handlers["ADD_TO_ACCESS_LIST"] = function(ctx, common, data, cb) {
var msg = data.msg;
var content = msg.content;
var channel = content.channel;
ctx.Store.getAllStores().forEach((function(store) {
var res = store.manager.findChannel(channel);
if (!res.length) {
return;
}
var data = res[0].data;
var id = res[0].id;
var teamId = store.id;
ctx.Store.loadSharedFolder(teamId, id, data, (function() {}), false);
}));
cb(true);
};
var addOwners = {};
handlers["ADD_OWNER"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
if (isMuted(ctx, data)) {
return void cb(true);
}
if (!content.teamChannel && !(content.href && content.title && content.channel)) {
console.log("Remove invalid notification");
return void cb(true);
}
var channel = content.channel || content.teamChannel;
if (content.password) {
content.pw = content.password;
content.password = encryptPassword(ctx, content.password);
}
if (addOwners[channel]) {
return void cb(true);
}
addOwners[channel] = {
type: box.type,
hash: data.hash
};
cb(false);
};
removeHandlers["ADD_OWNER"] = function(ctx, box, data) {
var channel = data.content.channel || data.content.teamChannel;
if (addOwners[channel]) {
delete addOwners[channel];
}
};
handlers["RM_OWNER"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
if (!content.channel && !content.teamChannel) {
console.log("Remove invalid notification");
return void cb(true);
}
var channel = content.channel || content.teamChannel;
if (content.teamChannel) {
var teams = ctx.store.proxy.teams || {};
Object.keys(teams).some((function(id) {
if (teams[id].channel === channel) {
teams[id].owner = false;
return true;
}
}));
}
if (addOwners[channel] && content.pending) {
return void cb(false, addOwners[channel]);
}
cb(false);
};
var invitedTo = {};
handlers["INVITE_TO_TEAM"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
if (isMuted(ctx, data)) {
return void cb(true);
}
if (!content.team) {
console.log("Remove invalid notification");
return void cb(true);
}
var invited = invitedTo[content.team.channel];
if (invited) {
console.log("removing old invitation");
cb(false, invited);
invitedTo[content.team.channel] = {
type: box.type,
hash: data.hash
};
return;
}
var myTeams = Util.find(ctx, [ "store", "proxy", "teams" ]) || {};
var alreadyMember = Object.keys(myTeams).some((function(k) {
var team = myTeams[k];
return team.channel === content.team.channel;
}));
if (alreadyMember) {
return void cb(true);
}
invitedTo[content.team.channel] = {
type: box.type,
hash: data.hash
};
cb(false);
};
removeHandlers["INVITE_TO_TEAM"] = function(ctx, box, data) {
var channel = Util.find(data, [ "content", "team", "channel" ]);
delete invitedTo[channel];
};
handlers["KICKED_FROM_TEAM"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
if (!content.teamChannel) {
console.log("Remove invalid notification");
return void cb(true);
}
if (invitedTo[content.teamChannel] && content.pending) {
return void cb(true, invitedTo[content.teamChannel]);
}
cb(false);
};
handlers["INVITE_TO_TEAM_ANSWER"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
if (!content.teamChannel) {
console.log("Remove invalid notification");
return void cb(true);
}
var myTeams = Util.find(ctx, [ "store", "proxy", "teams" ]) || {};
var teamId;
var team;
Object.keys(myTeams).some((function(k) {
var _team = myTeams[k];
if (_team.channel === content.teamChannel) {
teamId = k;
team = _team;
return true;
}
}));
if (!teamId) {
return void cb(true);
}
content.team = team;
if (!content.answer) {
try {
var module = ctx.store.modules["team"];
module.removeFromTeam(teamId, msg.author, true);
} catch (e) {
console.error(e);
}
}
var userData = content.user || content;
box.sendMessage({
type: "INVITE_TO_TEAM_ANSWERED",
content: {
user: userData,
team,
answer: content.answer
}
}, (function() {}));
cb(true);
};
handlers["TEAM_EDIT_RIGHTS"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
if (!content.teamData) {
console.log("Remove invalid notification");
return void cb(true);
}
var myTeams = Util.find(ctx, [ "store", "proxy", "teams" ]) || {};
var teamId;
Object.keys(myTeams).some((function(k) {
var _team = myTeams[k];
if (_team.channel === content.teamData.channel) {
teamId = k;
return true;
}
}));
if (!teamId) {
return void cb(true);
}
try {
var module = ctx.store.modules["team"];
module.changeMyRights(teamId, content.state, content.teamData, (function(done) {
if (!done) {
console.error("Can't update team rights");
}
cb(true);
}));
} catch (e) {
console.error(e);
}
};
handlers["OWNED_PAD_REMOVED"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
if (!content.channel) {
console.log("Remove invalid notification");
return void cb(true);
}
var channel = content.channel;
var res = ctx.store.manager.findChannel(channel);
res.forEach((function(obj) {
var paths = ctx.store.manager.findFile(obj.id);
ctx.store.manager.delete({
paths
}, (function() {
ctx.updateDrive();
}));
}));
cb(true);
};
handlers["MOVE_TODO"] = function(ctx, box, data, cb) {
var curve = ctx.store.proxy.curvePublic;
if (data.msg.author !== curve) {
return void cb(true);
}
cb();
};
handlers["SAFE_LINKS_DEFAULT"] = function(ctx, box, data, cb) {
var curve = ctx.store.proxy.curvePublic;
if (data.msg.author !== curve) {
return void cb(true);
}
cb();
};
var formNotifs = {};
handlers["FORM_RESPONSE"] = function(ctx, box, data, cb) {
var msg = data.msg;
var hash = data.hash;
var content = msg.content;
var channel = content.channel;
if (!channel) {
return void cb(true);
}
if (isChannelMuted(ctx, channel)) {
return void cb(true);
}
var title, href;
ctx.Store.getAllStores().some((function(s) {
var res = s.manager.findChannel(channel);
return res.some((function(obj) {
if (!obj.data) {
return;
}
if (href && !obj.data.href) {
return;
}
href = obj.data.href || obj.data.roHref;
title = obj.data.filename || obj.data.title;
if (obj.data.href) {
return true;
}
}));
}));
if (!href) {
return void cb(true);
}
content.href = href;
content.title = title;
var old = formNotifs[channel];
var toRemove = old ? old.data : undefined;
formNotifs[channel] = {
data: {
type: box.type,
hash
}
};
cb(false, toRemove);
};
removeHandlers["FORM_RESPONSE"] = function(ctx, box, data, hash) {
var content = data.content;
var channel = content.channel;
var old = formNotifs[channel];
if (old && old.data && old.data.hash === hash) {
delete formNotifs[channel];
}
};
var comments = {};
handlers["COMMENT_REPLY"] = function(ctx, box, data, cb) {
var msg = data.msg;
var hash = data.hash;
var content = msg.content;
if (Util.find(ctx.store.proxy, [ "settings", "pad", "disableNotif" ])) {
return void cb(true);
}
var channel = content.channel;
if (!channel) {
return void cb(true);
}
var title, href;
ctx.Store.getAllStores().some((function(s) {
var res = s.manager.findChannel(channel);
return res.some((function(obj) {
if (!obj.data) {
return;
}
if (href && !obj.data.href) {
return;
}
href = obj.data.href || obj.data.roHref;
title = obj.data.filename || obj.data.title;
if (obj.data.href) {
return true;
}
}));
}));
if (!href) {
return void cb(true);
}
content.href = href;
content.title = title;
var old = comments[channel];
var toRemove = old ? old.data : undefined;
comments[channel] = {
data: {
type: box.type,
hash
}
};
cb(false, toRemove);
};
removeHandlers["COMMENT_REPLY"] = function(ctx, box, data, hash) {
var content = data.content;
var channel = content.channel;
var old = comments[channel];
if (old && old.data && old.data.hash === hash) {
delete comments[channel];
}
};
var mentions = {};
handlers["MENTION"] = function(ctx, box, data, cb) {
var msg = data.msg;
var hash = data.hash;
var content = msg.content;
if (isMuted(ctx, data)) {
return void cb(true);
}
var channel = content.channel;
if (!channel) {
return void cb(true);
}
var title, href;
ctx.Store.getAllStores().some((function(s) {
var res = s.manager.findChannel(channel);
return res.some((function(obj) {
if (!obj.data) {
return;
}
if (href && !obj.data.href) {
return;
}
href = obj.data.href || obj.data.roHref;
title = obj.data.filename || obj.data.title;
if (obj.data.href) {
return true;
}
}));
}));
content.href = href;
content.title = title;
var old = mentions[channel];
var toRemove = old ? old.data : undefined;
mentions[channel] = {
data: {
type: box.type,
hash
}
};
cb(false, toRemove);
};
removeHandlers["MENTION"] = function(ctx, box, data, hash) {
var content = data.content;
var channel = content.channel;
var old = mentions[channel];
if (old && old.data && old.data.hash === hash) {
delete mentions[channel];
}
};
handlers["BROADCAST_MAINTENANCE"] = function(ctx, box, data, cb) {
var msg = data.msg;
var uid = msg.uid;
ctx.Store.onMaintenanceUpdate(uid);
cb(true);
};
var activeSurvey;
handlers["BROADCAST_SURVEY"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
var uid = msg.uid;
var old = activeSurvey;
activeSurvey = {
type: box.type,
hash: data.hash
};
ctx.Store.onSurveyUpdate(uid);
var dismiss = !content.url;
cb(dismiss, old);
};
var activeCustom;
handlers["BROADCAST_CUSTOM"] = function(ctx, box, data, cb) {
var msg = data.msg;
var uid = msg.uid;
var old = activeCustom;
activeCustom = {
uid,
type: box.type,
hash: data.hash
};
cb(false, old);
};
handlers["BROADCAST_DELETE"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
var uid = content.uid;
if (activeCustom && activeCustom.uid === uid) {
cb(true, activeCustom);
activeCustom = undefined;
return;
}
cb(true);
};
var sfDeleted = {};
handlers["SF_DELETED"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
var teamId = content.team;
var sfId = content.sfId;
if (sfDeleted[sfId]) {
return void cb(true);
}
sfDeleted[sfId] = 1;
if (!teamId) {
return void cb(false);
}
var team = ctx.store.proxy.teams[teamId];
content.teamName = team.metadata && team.metadata.name;
cb(false);
};
removeHandlers["SF_DELETED"] = function(ctx, box, data) {
var id = data.content.sfId;
delete sfDeleted[id];
};
handlers["NEW_TICKET"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
if (!content.time) {
content.time = data.time;
}
var support = Util.find(ctx, [ "store", "modules", "support" ]);
if (content.isAdmin) {
support.addUserTicket(content, cb);
}
support.addAdminTicket(content, cb);
};
var supportNotif, adminSupportNotif;
handlers["NOTIF_TICKET"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
if (!content.time) {
content.time = data.time;
}
var support = Util.find(ctx, [ "store", "modules", "support" ]);
if (content.isAdmin) {
let exists = Util.find(ctx, [ "store", "proxy", "support", content.channel ]);
if (!exists) {
return void cb(true);
}
support.updateUserTicket(content);
if (supportNotif) {
return void cb(false, supportNotif);
}
supportNotif = {
channel: content.channel,
type: box.type,
hash: data.hash
};
return void cb(false);
}
support.checkAdminTicket(content, (exists => {
if (!exists) {
return void cb(true);
}
support.updateAdminTicket(content);
if (Util.find(ctx.store.proxy, [ "settings", "general", "disableSupportNotif" ])) {
return void cb(true);
}
if (adminSupportNotif) {
return void cb(false, adminSupportNotif);
}
adminSupportNotif = {
channel: content.channel,
type: box.type,
hash: data.hash
};
cb(false);
}));
};
removeHandlers["NOTIF_TICKET"] = function(ctx, box, data) {
var id = data.content.channel;
if (supportNotif && supportNotif.channel === id) {
supportNotif = undefined;
}
if (adminSupportNotif && adminSupportNotif.channel === id) {
adminSupportNotif = undefined;
}
};
handlers["ADD_MODERATOR"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
var support = Util.find(ctx, [ "store", "modules", "support" ]);
support.updateAdminKey(content, cb);
};
handlers["MODERATOR_NEW_KEY"] = function(ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
var support = Util.find(ctx, [ "store", "modules", "support" ]);
support.updateAdminKey(content, (function() {
cb(true);
}));
};
return {
add: function(ctx, box, data, cb) {
if (!data.msg) {
return void cb(null, null, true);
}
var myCurve = Util.find(ctx, [ "store", "proxy", "curvePublic" ]);
var curve = Util.find(data, [ "msg", "content", "user", "curvePublic" ]) || Util.find(data, [ "msg", "content", "curvePublic" ]);
if (curve && data.msg.author !== curve && data.msg.author !== myCurve) {
console.error("blocked");
return void cb(null, null, true);
}
var type = data.msg.type;
if (handlers[type]) {
try {
handlers[type](ctx, box, data, cb);
} catch (e) {
console.error(e);
cb();
}
} else {
cb();
}
},
remove: function(ctx, box, data, h) {
if (!data) {
return;
}
var type = data.type;
if (removeHandlers[type]) {
try {
removeHandlers[type](ctx, box, data, h);
} catch (e) {
console.error(e);
}
}
}
};
};
if (module.exports) {
module.exports = factory(requireCommonMessaging(), requireCommonHash(), requireCommonUtil(), requireCrypto(), requireLoginBlock());
}
})();
})(mailboxHandlers);
return mailboxHandlers.exports;
}
var hasRequiredMailbox;
function requireMailbox() {
if (hasRequiredMailbox) return mailbox$1.exports;
hasRequiredMailbox = 1;
(function(module) {
(() => {
const factory = (BCast = {}, Util, Hash, Realtime, Messaging, Notify, Handlers, CpNetflux, Crypto) => {
var Mailbox = {};
Mailbox.setCustomize = data => {
BCast = data.Broadcast;
};
var TYPES = [ "notifications", "supportteam", "broadcast" ];
var BLOCKING_TYPES = [];
var BROADCAST_CHAN = "000000000000000000000000000000000";
var initializeMailboxes = function(ctx, mailboxes) {
if (!mailboxes["notifications"] && ctx.loggedIn) {
mailboxes.notifications = {
channel: Hash.createChannelId(),
lastKnownHash: "",
viewed: []
};
ctx.pinPads([ mailboxes.notifications.channel ], (function(res) {
if (res.error) {
console.error(res);
}
}));
}
if (mailboxes.support) {
delete mailboxes.support;
}
if (!mailboxes["broadcast"]) {
mailboxes.broadcast = {
channel: BROADCAST_CHAN,
lastKnownHash: BCast.lastBroadcastHash,
decrypted: true,
viewed: []
};
}
};
var isMessageNew = function(hash, m) {
return (m.viewed || []).indexOf(hash) === -1 && hash !== m.lastKnownHash;
};
var showMessage = function(ctx, type, msg, cId, cb) {
ctx.emit("MESSAGE", {
type,
content: msg
}, cId ? [ cId ] : ctx.clients, cb);
};
var hideMessage = function(ctx, type, hash, clients) {
ctx.emit("VIEWED", {
type,
hash
}, clients || ctx.clients);
};
var getMyKeys = function(ctx) {
var proxy = ctx.store && ctx.store.proxy;
if (!proxy.curvePrivate || !proxy.curvePublic) {
return;
}
return {
curvePrivate: proxy.curvePrivate,
curvePublic: proxy.curvePublic
};
};
var sendTo = Mailbox.sendTo = function(ctx, type, msg, user, _cb) {
user = user || {};
var cb = _cb || function(obj) {
if (obj && obj.error) {
console.error(obj.error);
}
};
if (!Crypto.Mailbox) {
return void cb({
error: "chainpad-crypto is outdated and doesn't support mailboxes."
});
}
var anonRpc = Util.find(ctx, [ "store", "anon_rpc" ]);
if (!anonRpc) {
return void cb({
error: "anonymous rpc session not ready"
});
}
var crypto = {
encrypt: function(x) {
return x;
}
};
var channel = BROADCAST_CHAN;
var obj = {
uid: Util.uid(),
type,
content: msg
};
if (!/^BROADCAST/.test(type)) {
var keys = getMyKeys(ctx);
if (!keys) {
return void cb({
error: "missing asymmetric encryption keys"
});
}
if (!user || !user.channel || !user.curvePublic) {
return void cb({
error: "no notification channel"
});
}
channel = user.channel;
crypto = Crypto.Mailbox.createEncryptor(keys);
if (typeof msg === "object" && !msg.user) {
var myData = Messaging.createData(ctx.store.proxy, false);
msg.user = myData;
}
obj = {
type,
content: msg
};
}
var text = JSON.stringify(obj);
var ciphertext = crypto.encrypt(text, user.curvePublic);
if (user.viewed) {
var team = Util.find(ctx, [ "store", "proxy", "teams", user.viewed ]);
if (team) {
var hash = ciphertext.slice(0, 64);
var viewed = Util.find(team, [ "keys", "mailbox", "viewed" ]);
if (Array.isArray(viewed)) {
viewed.push(hash);
}
}
}
anonRpc.send("WRITE_PRIVATE_MESSAGE", [ channel, ciphertext ], (function(err) {
if (err) {
return void cb({
error: err
});
}
return void cb({
hash: ciphertext.slice(0, 64)
});
}));
};
Mailbox.sendToAnon = function(anonRpc, type, msg, user, cb) {
var Nacl = Crypto.Nacl;
var curveSeed = Nacl.randomBytes(32);
var curvePair = Nacl.box.keyPair.fromSecretKey(new Uint8Array(curveSeed));
var curvePrivate = Nacl.util.encodeBase64(curvePair.secretKey);
var curvePublic = Nacl.util.encodeBase64(curvePair.publicKey);
sendTo({
store: {
anon_rpc: anonRpc,
proxy: {
curvePrivate,
curvePublic
}
}
}, type, msg, user, cb);
};
var dismiss = function(ctx, data, cId, cb) {
var type = data.type;
var hash = data.hash;
if (/^REMINDER\|/.test(hash)) {
cb();
delete ctx.boxes.reminders.content[hash];
hideMessage(ctx, type, hash, ctx.clients.filter((function(clientId) {
return clientId !== cId;
})));
var uid = hash.slice(9).split("-")[0];
var d = Util.find(ctx, [ "store", "proxy", "hideReminders", uid ]);
if (!d) {
var h = ctx.store.proxy.hideReminders = ctx.store.proxy.hideReminders || {};
d = h[uid] = h[uid] || [];
}
var delay = hash.split("-")[1];
if (delay && !d.includes(delay)) {
d.push(Number(delay));
}
return;
}
var box = ctx.boxes[type];
if (!box) {
return void cb({
error: "NOT_LOADED"
});
}
var m = box.data || {};
var idx = box.history.indexOf(hash);
if (idx !== -1) {
if (idx === 0) {
m.lastKnownHash = hash;
box.history.shift();
} else if (m.viewed.indexOf(hash) === -1) {
m.viewed.push(hash);
}
}
var sliceIdx;
var lastKnownHash;
var toForget = [];
box.history.some((function(hash, i) {
var isViewed = m.viewed.indexOf(hash);
if (isViewed === -1) {
return true;
}
sliceIdx = i + 1;
toForget.push(hash);
lastKnownHash = hash;
}));
m.viewed = m.viewed.filter((function(hash) {
return toForget.indexOf(hash) === -1;
}));
if (sliceIdx) {
box.history = box.history.slice(sliceIdx);
m.lastKnownHash = lastKnownHash;
}
Object.keys(box.content).forEach((function(h) {
if (box.history.indexOf(h) === -1 || m.viewed.indexOf(h) !== -1) {
Handlers.remove(ctx, box, box.content[h], h);
delete box.content[h];
}
}));
Realtime.whenRealtimeSyncs(ctx.store.realtime, (function() {
cb();
hideMessage(ctx, type, hash, ctx.clients.filter((function(clientId) {
return clientId !== cId;
})));
}));
};
var leaveChannel = function(ctx, type, cb) {
cb = cb || function() {};
var box = ctx.boxes[type];
if (!box) {
return void cb();
}
if (!box.cpNf || typeof box.cpNf.stop !== "function") {
return void cb("EINVAL");
}
box.cpNf.stop();
Object.keys(box.content).forEach((function(h) {
Handlers.remove(ctx, box, box.content[h], h);
hideMessage(ctx, type, h, ctx.clients);
}));
delete ctx.boxes[type];
};
var openChannel = function(ctx, type, m, onReady, opts) {
opts = opts || {};
var box = ctx.boxes[type] = {
channel: m.channel,
type,
queue: [],
history: [],
content: {},
sendMessage: function(msg) {
if (typeof msg === "object" && !msg.user) {
var myData = Messaging.createData(ctx.store.proxy, false);
msg.user = myData;
}
try {
msg = JSON.stringify(msg);
} catch (e) {
console.error(e);
}
box.queue.push(msg);
},
data: m
};
if (!Crypto.Mailbox) {
return void console.error("chainpad-crypto is outdated and doesn't support mailboxes.");
}
var keys = m.keys || getMyKeys(ctx);
if (!keys && !m.decrypted) {
return void console.error("missing asymmetric encryption keys");
}
var crypto = m.decrypted ? {
encrypt: function(x) {
return x;
},
decrypt: function(x) {
return x;
}
} : Crypto.Mailbox.createEncryptor(keys);
box.encryptor = crypto;
var cfg = {
network: ctx.store.network,
channel: m.channel,
noChainPad: true,
crypto,
owners: type === "broadcast" ? [] : opts.owners || [ ctx.store.proxy.edPublic ],
lastKnownHash: m.lastKnownHash
};
cfg.onConnectionChange = function() {};
cfg.onConnect = function(wc, sendMessage) {
box.sendMessage = function(_msg, cb) {
cb = cb || function() {};
var msg;
try {
msg = JSON.stringify(_msg);
} catch (e) {
console.error(e);
}
sendMessage(msg, (function(err, hash) {
if (err) {
return void console.error(err);
}
box.history.push(hash);
_msg.ctime = +new Date;
box.content[hash] = _msg;
var message = {
msg: _msg,
hash
};
showMessage(ctx, type, message);
cb(hash);
}), keys.curvePublic);
};
box.queue.forEach((function(msg) {
box.sendMessage(msg);
}));
box.queue = [];
};
var lastReceivedHash;
box.onMessage = cfg.onMessage = function(msg, user, vKey, isCp, hash, author, data) {
if (hash === m.lastKnownHash) {
return;
}
if (hash === lastReceivedHash) {
return;
}
var time = data && data.time;
lastReceivedHash = hash;
try {
msg = JSON.parse(msg);
} catch (e) {
console.error(e);
}
if (author) {
msg.author = author;
}
box.history.push(hash);
if (isMessageNew(hash, m)) {
var message = {
msg,
hash,
time
};
var notify = box.ready;
Handlers.add(ctx, box, message, (function(dismissed, toDismiss, invalid) {
if (toDismiss) {
dismiss(ctx, toDismiss, "", (function() {
console.log("Notification handled automatically");
}));
}
if (invalid || dismissed) {
dismiss(ctx, {
type,
hash
}, "", (function() {
console.log("Notification handled automatically");
}));
return;
}
msg.ctime = time || 0;
box.content[hash] = msg;
if (opts.dump) {
return;
}
showMessage(ctx, type, message, null, (function(obj) {
if (!obj || !obj.msg || !notify) {
return;
}
Notify.system(undefined, obj.msg);
}));
}));
} else {
if (Object.keys(box.content).length === 0) {
m.lastKnownHash = hash;
box.history = [];
var idxViewed = m.viewed.indexOf(hash);
if (idxViewed !== -1) {
m.viewed.splice(idxViewed, 1);
}
}
}
};
cfg.onReady = function() {
var toClean = [];
m.viewed.forEach((function(h, i) {
if (box.history.indexOf(h) === -1) {
toClean.push(i);
}
}));
for (var i = toClean.length - 1; i >= 0; i--) {
m.viewed.splice(toClean[i], 1);
}
var view = function(h) {
Handlers.remove(ctx, box, box.content[h], h);
delete box.content[h];
hideMessage(ctx, type, h);
};
ctx.store.proxy.on("change", [ "mailboxes", type ], (function(o, n, p) {
if (p[2] === "lastKnownHash") {
var sliceIdx;
box.history.some((function(h, i) {
sliceIdx = i + 1;
view(h);
if (h === n) {
return true;
}
}));
box.history = box.history.slice(sliceIdx);
}
if (p[2] === "viewed") {
view(n);
}
}));
box.ready = true;
onReady(box.content);
};
box.cpNf = CpNetflux.start(cfg);
};
var initializeHistory = function(ctx) {
var network = ctx.store.network;
network.on("message", (function(msg, sender) {
if (sender !== network.historyKeeper) {
return;
}
var parsed = JSON.parse(msg);
if (!/HISTORY_RANGE/.test(parsed[0])) {
return;
}
var txid = parsed[1];
var req = ctx.req[txid];
if (!req) {
return;
}
var type = parsed[0];
var _msg = parsed[2];
var box = req.box;
if (type === "HISTORY_RANGE") {
if (!Array.isArray(_msg)) {
return;
}
var message;
if (req.box.type === "broadcast") {
message = Util.tryParse(_msg[4]);
} else {
try {
var decrypted = box.encryptor.decrypt(_msg[4]);
message = JSON.parse(decrypted.content);
message.author = decrypted.author;
} catch (e) {
console.log(e);
}
}
var hash = _msg[4].slice(0, 64);
ctx.emit("HISTORY", {
txid,
time: _msg[5],
message,
hash
}, [ req.cId ]);
} else if (type === "HISTORY_RANGE_END") {
ctx.emit("HISTORY", {
txid,
complete: true
}, [ req.cId ]);
delete ctx.req[txid];
}
}));
};
var loadHistory = function(ctx, clientId, data, cb) {
var box = ctx.boxes[data.type];
if (!box) {
return void cb({
error: "ENOENT"
});
}
var msg = [ "GET_HISTORY_RANGE", box.channel, {
from: data.lastKnownHash,
count: data.count,
txid: data.txid
} ];
if (data.type === "broadcast") {
msg = [ "GET_HISTORY_RANGE", box.channel, {
to: data.lastKnownHash,
txid: data.txid
} ];
}
ctx.req[data.txid] = {
cId: clientId,
box
};
var network = ctx.store.network;
network.sendto(network.historyKeeper, JSON.stringify(msg)).then((function() {}), (function(err) {
console.error(err);
}));
};
var subscribe = function(ctx, data, cId, cb) {
Object.keys(ctx.boxes).forEach((function(type) {
Object.keys(ctx.boxes[type].content).forEach((function(h) {
var message = {
msg: ctx.boxes[type].content[h],
hash: h
};
showMessage(ctx, type, message, cId, (function(obj) {
if (obj.error) {
return;
}
if (!message.msg || !message.msg.requiresNotif) {
return;
}
Notify.system(undefined, obj.msg);
delete message.msg.requiresNotif;
}));
}));
}));
var idx = ctx.clients.indexOf(cId);
if (idx === -1) {
ctx.clients.push(cId);
}
cb();
};
var removeClient = function(ctx, cId) {
var idx = ctx.clients.indexOf(cId);
ctx.clients.splice(idx, 1);
};
Mailbox.init = function(cfg, waitFor, emit) {
var mailbox = {};
var store = cfg.store;
var mailboxes = store.proxy.mailboxes = store.proxy.mailboxes || {};
var ctx = {
Store: cfg.Store,
store,
pinPads: cfg.pinPads,
updateMetadata: cfg.updateMetadata,
updateDrive: cfg.updateDrive,
mailboxes,
emit,
clients: [],
boxes: {},
req: {},
loggedIn: store.loggedIn && store.proxy.edPublic
};
initializeMailboxes(ctx, mailboxes);
if (ctx.loggedIn) {
initializeHistory(ctx);
}
ctx.boxes.reminders = {
content: {}
};
Object.keys(mailboxes).forEach((function(key) {
if (TYPES.indexOf(key) === -1) {
return;
}
var m = mailboxes[key];
if (BLOCKING_TYPES.indexOf(key) === -1) {
openChannel(ctx, key, m, (function() {}));
} else {
openChannel(ctx, key, m, waitFor((function() {})));
}
}));
if (ctx.loggedIn) {
Object.keys(store.proxy.teams || {}).forEach((function(teamId) {
var team = store.proxy.teams[teamId];
if (!team) {
return;
}
var teamMailbox = team.keys.mailbox || {};
if (!teamMailbox.channel) {
return;
}
var opts = {
owners: [ Util.find(team, [ "keys", "drive", "edPublic" ]) ]
};
openChannel(ctx, "team-" + teamId, teamMailbox, (function() {}), opts);
}));
}
mailbox.post = function(box, type, content) {
var b = ctx.boxes[box];
if (!b) {
return;
}
b.sendMessage({
type,
content,
sender: store.proxy.curvePublic
});
};
mailbox.hideMessage = function(type, msg) {
hideMessage(ctx, type, msg.hash, ctx.clients);
};
mailbox.showMessage = function(type, msg, cId, cb) {
if (type === "reminders" && msg) {
ctx.boxes.reminders.content[msg.hash] = msg.msg;
if (!ctx.clients.length) {
ctx.boxes.reminders.content[msg.hash].requiresNotif = true;
}
hideMessage(ctx, type, msg.hash, ctx.clients);
}
showMessage(ctx, type, msg, cId, (function(obj) {
Notify.system(undefined, obj.msg);
if (cb) {
cb();
}
}));
};
mailbox.open = function(key, m, cb, team, opts) {
if (TYPES.indexOf(key) === -1 && !team) {
return;
}
openChannel(ctx, key, m, cb, opts);
};
mailbox.close = function(key, cb) {
leaveChannel(ctx, key, cb);
};
mailbox.dismiss = function(data, cb) {
dismiss(ctx, data, "", cb);
};
mailbox.sendTo = function(type, msg, user, cb) {
if (!ctx.loggedIn) {
return void cb({
error: "NOT_LOGGED_IN"
});
}
sendTo(ctx, type, msg, user, cb);
};
mailbox.removeClient = function(clientId) {
removeClient(ctx, clientId);
};
mailbox.execCommand = function(clientId, obj, cb) {
var cmd = obj.cmd;
var data = obj.data;
if (cmd === "SUBSCRIBE") {
return void subscribe(ctx, data, clientId, cb);
}
if (cmd === "DISMISS") {
return void dismiss(ctx, data, clientId, cb);
}
if (cmd === "SENDTO") {
return void sendTo(ctx, data.type, data.msg, data.user, cb);
}
if (cmd === "LOAD_HISTORY") {
return void loadHistory(ctx, clientId, data, cb);
}
};
return mailbox;
};
return Mailbox;
};
if (module.exports) {
module.exports = factory(undefined, requireCommonUtil(), requireCommonHash(), requireCommonRealtime(), requireCommonMessaging(), requireNotify(), requireMailboxHandlers(), requireChainpadNetflux(), requireCrypto());
}
})();
})(mailbox$1);
return mailbox$1.exports;
}
var hasRequiredMigrateUserObject;
function requireMigrateUserObject() {
if (hasRequiredMigrateUserObject) return migrateUserObject$1.exports;
hasRequiredMigrateUserObject = 1;
(function(module) {
(() => {
const factory = (Feedback, Hash, Util, Messaging, Crypt, Mailbox, Messages = {}, Realtime, nThen, Crypto) => {
const setCustomize = data => {
Messages = data.Messages;
};
let migrate = function(userObject, cb, progress, store) {
var version = userObject.version || 0;
nThen((function() {})).nThen((function() {
var migrateAttributes = function() {
var drawer = "cryptpad.userlist-drawer";
var polls = "cryptpad.hide_poll_text";
var indentKey = "cryptpad.indentUnit";
var useTabsKey = "cryptpad.indentWithTabs";
var settings = userObject.settings = userObject.settings || {};
if (typeof userObject[indentKey] !== "undefined") {
settings.codemirror = settings.codemirror || {};
settings.codemirror.indentUnit = userObject[indentKey];
delete userObject[indentKey];
}
if (typeof userObject[useTabsKey] !== "undefined") {
settings.codemirror = settings.codemirror || {};
settings.codemirror.indentWithTabs = userObject[useTabsKey];
delete userObject[useTabsKey];
}
if (typeof userObject[drawer] !== "undefined") {
settings.toolbar = settings.toolbar || {};
settings.toolbar["userlist-drawer"] = userObject[drawer];
delete userObject[drawer];
}
if (typeof userObject[polls] !== "undefined") {
settings.poll = settings.poll || {};
settings.poll["hide-text"] = userObject[polls];
delete userObject[polls];
}
};
if (version < 2) {
migrateAttributes();
Feedback.send("Migrate-2", true);
userObject.version = version = 2;
}
})).nThen((function() {
var migrateLanguage = function() {
if (!localStorage.CRYPTPAD_LANG) {
return;
}
var l = localStorage.CRYPTPAD_LANG;
userObject.settings.language = l;
};
if (version < 3) {
migrateLanguage();
Feedback.send("Migrate-3", true);
userObject.version = version = 3;
}
})).nThen((function() {
var migrateFeedback = function() {
var settings = userObject.settings = userObject.settings || {};
if (typeof userObject["allowUserFeedback"] !== "undefined") {
settings.general = settings.general || {};
settings.general.allowUserFeedback = userObject["allowUserFeedback"];
delete userObject["allowUserFeedback"];
}
};
if (version < 4) {
migrateFeedback();
Feedback.send("Migrate-4", true);
userObject.version = version = 4;
}
})).nThen((function() {
var migrateDates = function() {
var data = userObject.drive && userObject.drive.filesData;
if (data) {
for (var id in data) {
if (typeof data[id].ctime !== "number") {
data[id].ctime = +new Date(data[id].ctime);
}
if (typeof data[id].atime !== "number") {
data[id].atime = +new Date(data[id].atime);
}
}
}
};
if (version < 5) {
migrateDates();
Feedback.send("Migrate-5", true);
userObject.version = version = 5;
}
})).nThen((function(waitFor) {
var addChannelId = function() {
var data = userObject.drive.filesData || {};
var el, parsed;
var n = nThen((function() {}));
var padsLength = Object.keys(data).length;
Object.keys(data).forEach((function(k, i) {
n = n.nThen((function(w) {
setTimeout(w((function() {
el = data[k];
parsed = Hash.parsePadUrl(el.href);
if (!el.href) {
return;
}
if (!el.channel) {
var secret = Hash.getSecrets(parsed.type, parsed.hash, el.password);
el.channel = secret.channel;
progress(6, Math.round(100 * i / padsLength));
console.log("Adding missing channel in filesData ", el.channel);
}
})));
}));
}));
n.nThen(waitFor((function() {
Feedback.send("Migrate-6", true);
userObject.version = version = 6;
})));
};
if (version < 6) {
addChannelId();
}
})).nThen((function(waitFor) {
var addRoHref = function() {
var data = userObject.drive.filesData;
var el, parsed;
var n = nThen((function() {}));
var padsLength = Object.keys(data).length;
Object.keys(data).forEach((function(k, i) {
n = n.nThen((function(w) {
setTimeout(w((function() {
el = data[k];
if (!el.href) {
return void progress(7, Math.round(100 * i / padsLength));
}
if (el.href.indexOf("#") === -1) {
return void progress(7, Math.round(100 * i / padsLength));
}
parsed = Hash.parsePadUrl(el.href);
if (parsed.hashData.type !== "pad") {
return void progress(7, Math.round(100 * i / padsLength));
}
if (parsed.hashData.mode === "view") {
el.roHref = el.href;
delete el.href;
console.log("Move href to roHref in filesData ", el.roHref);
} else {
var secret = Hash.getSecrets(parsed.type, parsed.hash, el.password);
var hash = Hash.getViewHashFromKeys(secret);
if (hash) {
el.roHref = "/" + parsed.type + "/#" + hash;
console.log("Adding missing roHref in filesData ", el.href);
}
}
progress(6, Math.round(100 * i / padsLength));
})));
}));
}));
n.nThen(waitFor((function() {
Feedback.send("Migrate-7", true);
userObject.version = version = 7;
})));
};
if (version < 7) {
addRoHref();
}
})).nThen((function() {
var fixDuplicate = function() {
userObject.FS_hashes = Util.deduplicateString(userObject.FS_hashes || []);
};
if (version < 8) {
fixDuplicate();
Feedback.send("Migrate-8", true);
userObject.version = version = 8;
}
})).nThen((function() {
var migrateFriends = function() {
var network = store.network;
var channels = {};
var ctx = {
store
};
var myData = Messaging.createData(userObject);
var close = function(chan) {
var channel = channels[chan];
if (!channel) {
return;
}
try {
channel.wc.leave();
} catch (e) {}
delete channels[chan];
};
var onDirectMessage = function(msg, sender) {
if (sender !== network.historyKeeper) {
return;
}
var parsed = JSON.parse(msg);
if ((parsed.validateKey || parsed.owners) && parsed.channel) {
return;
}
if (parsed.channel && channels[parsed.channel]) {
if (parsed.error && parsed.error === "EINVAL") {
var histMsg = [ "GET_HISTORY", parsed.channel, {} ];
network.sendto(network.historyKeeper, JSON.stringify(histMsg)).then((function() {}), (function() {}));
return;
}
if (parsed.state && parsed.state === 1) {
myData.channel = parsed.channel;
var updateMsg = [ "UPDATE", myData.curvePublic, +new Date, myData ];
var cryptMsg = channels[parsed.channel].encrypt(JSON.stringify(updateMsg));
channels[parsed.channel].wc.bcast(cryptMsg).then((function() {}), (function(err) {
console.error("Can't migrate this friend", channels[parsed.channel].friend, err);
}));
close(parsed.channel);
return;
}
} else if (parsed.channel) {
return;
}
var chan = parsed[3];
if (!chan || !channels[chan]) {
return;
}
var channel = channels[chan];
var msgIn = channel.decrypt(parsed[4]);
var parsedMsg = JSON.parse(msgIn);
if (parsedMsg[0] === "UPDATE") {
if (parsedMsg[1] === myData.curvePublic) {
return;
}
var data = parsedMsg[3];
if (!data.notifications) {
return;
}
channel.friend.notifications = data.notifications;
myData.channel = chan;
Mailbox.sendTo(ctx, "UPDATE_DATA", myData, {
channel: data.notifications,
curvePublic: data.curvePublic
}, (function(obj) {
if (obj && obj.error) {
return void console.error(obj);
}
console.log("friend migrated", channel.friend);
}));
close(chan);
}
};
network.on("message", (function(msg, sender) {
try {
onDirectMessage(msg, sender);
} catch (e) {
console.error(e);
}
}));
var friends = userObject.friends || {};
Object.keys(friends).forEach((function(curve) {
if (curve.length !== 44) {
return;
}
var friend = friends[curve];
if (friend.notifications) {
return;
}
network.join(friend.channel).then((function(wc) {
var keys = Crypto.Curve.deriveKeys(friend.curvePublic, userObject.curvePrivate);
var encryptor = Crypto.Curve.createEncryptor(keys);
channels[friend.channel] = {
wc,
friend,
decrypt: encryptor.decrypt,
encrypt: encryptor.encrypt
};
var cfg = {
lastKnownHash: friend.lastKnownHash
};
var msg = [ "GET_HISTORY", friend.channel, cfg ];
network.sendto(network.historyKeeper, JSON.stringify(msg)).then((function() {}), (function(err) {
console.error("Can't migrate this friend", friend, err);
}));
}), (function(err) {
console.error("Can't migrate this friend", friend, err);
}));
}));
};
if (version < 9) {
migrateFriends();
Feedback.send("Migrate-9", true);
userObject.version = version = 9;
}
})).nThen((function(waitFor) {
var fixTodo = function() {
var h = store.proxy.todo;
if (!h) {
return;
}
var next = waitFor((function() {
Feedback.send("Migrate-10", true);
userObject.version = version = 10;
}));
var old;
var opts = {
network: store.network,
initialState: "{}",
metadata: {
owners: store.proxy.edPublic ? [ store.proxy.edPublic ] : []
}
};
nThen((function(w) {
Crypt.get(h, w((function(err, val) {
if (err || !val) {
w.abort();
next();
return;
}
try {
old = JSON.parse(val);
} catch (e) {}
})), opts);
})).nThen((function(w) {
if (!old || typeof old !== "object") {
w.abort();
next();
return;
}
var k = {
content: {
data: {
1: {
id: "1",
color: "color6",
item: [],
title: Messages.kanban_todo
},
2: {
id: "2",
color: "color3",
item: [],
title: Messages.kanban_working
},
3: {
id: "3",
color: "color5",
item: [],
title: Messages.kanban_done
}
},
items: {},
list: [ 1, 2, 3 ]
},
metadata: {
title: Messages.type.todo,
defaultTitle: Messages.type.todo,
type: "kanban"
}
};
var i = 4;
var items = false;
(old.order || []).forEach((function(key) {
var data = old.data[key];
if (!data || !data.task) {
return;
}
items = true;
var column = data.state ? "3" : "1";
k.content.data[column].item.push(i);
k.content.items[i] = {
id: i,
title: data.task
};
i++;
}));
if (!items) {
w.abort();
next();
return;
}
var newH = Hash.createRandomHash("kanban");
var secret = Hash.getSecrets("kanban", newH);
var oldSecret = Hash.getSecrets("todo", h);
Crypt.put(newH, JSON.stringify(k), w((function(err) {
if (err) {
w.abort();
next();
return;
}
if (store.rpc) {
store.rpc.pin([ secret.channel ], (function() {}));
store.rpc.unpin([ oldSecret.channel ], (function() {}));
}
var href = Hash.hashToHref(newH, "kanban");
store.manager.addPad([ "root" ], {
title: Messages.type.todo,
owners: opts.metadata.owners,
channel: secret.channel,
href,
roHref: Hash.hashToHref(Hash.getViewHashFromKeys(secret), "kanban"),
atime: +new Date,
ctime: +new Date
}, w((function(e) {
if (e) {
return void console.error(e);
}
delete store.proxy.todo;
var myData = Messaging.createData(userObject);
var ctx = {
store
};
Mailbox.sendTo(ctx, "MOVE_TODO", {
user: myData,
href
}, {
channel: myData.notifications,
curvePublic: myData.curvePublic
}, (function(obj) {
if (obj && obj.error) {
return void console.error(obj);
}
}));
})));
})), opts);
})).nThen((function() {
next();
}));
};
if (version < 10) {
fixTodo();
}
})).nThen((function(waitFor) {
if (version >= 11) {
return;
}
var done = function() {
Feedback.send("Migrate-11", true);
userObject.version = version = 11;
};
var unsafeLinks = Util.find(userObject, [ "settings", "security", "unsafeLinks" ]);
if (unsafeLinks !== undefined) {
return void done();
}
var ctx = {
store
};
var myData = Messaging.createData(userObject);
if (!myData.curvePublic) {
return void done();
}
Mailbox.sendTo(ctx, "SAFE_LINKS_DEFAULT", {
user: myData
}, {
channel: myData.notifications,
curvePublic: myData.curvePublic
}, waitFor((function(obj) {
if (obj && obj.error) {
return void console.error(obj);
}
done();
})));
})).nThen((function() {
Realtime.whenRealtimeSyncs(store.realtime, Util.mkAsync(Util.bake(cb)));
}));
};
migrate.setCustomize = setCustomize;
return migrate;
};
if (module.exports) {
module.exports = factory(requireCommonFeedback(), requireCommonHash(), requireCommonUtil(), requireCommonMessaging(), requireCryptget(), requireMailbox(), undefined, requireCommonRealtime(), requireNthen(), requireCrypto());
}
})();
})(migrateUserObject$1);
return migrateUserObject$1.exports;
}
var mergeDrive = {
exports: {}
};
var hasRequiredMergeDrive;
function requireMergeDrive() {
if (hasRequiredMergeDrive) return mergeDrive.exports;
hasRequiredMergeDrive = 1;
(function(module) {
(() => {
const factory = (Crypt, FO, Hash, Realtime) => {
var exp = {};
exp.anonDriveIntoUser = function(proxyData, fsHash, cb) {
if (!fsHash || !proxyData.loggedIn) {
if (typeof cb === "function") {
return void cb();
}
}
var todo = function(err, doc) {
if (err) {
console.error("Cannot migrate recent pads", err);
return;
}
var parsed;
if (!doc) {
if (typeof cb === "function") {
cb();
}
return;
}
try {
parsed = JSON.parse(doc);
} catch (e) {
if (typeof cb === "function") {
cb();
}
console.error("Cannot parsed recent pads", e);
return;
}
if (parsed) {
var proxy = proxyData.proxy;
var oldFo = FO.init(parsed.drive, {
readOnly: false,
loggedIn: true,
outer: true
});
var onMigrated = function() {
oldFo.fixFiles(true);
var manager = proxyData.manager;
var oldFiles = oldFo.getFiles([ oldFo.FILES_DATA ]);
oldFiles.forEach((function(id) {
var data = oldFo.getFileData(id);
var channel = data.channel;
var datas = manager.findChannel(channel);
if (datas.length !== 0) {
if (!data.href) {
return;
}
datas.forEach((function(pad) {
if (pad.data && !pad.data.href) {
pad.userObject.setHref(channel, null, data.href);
}
}));
return;
}
if (data) {
manager.addPad(null, data, (function(err) {
if (err) {
return void console.error("Cannot import file:", data, err);
}
}));
}
}));
if (!proxy.FS_hashes || !Array.isArray(proxy.FS_hashes)) {
proxy.FS_hashes = [];
}
if (proxy.FS_hashes.indexOf(fsHash) === -1) {
proxy.FS_hashes.push(fsHash);
}
if (typeof cb === "function") {
Realtime.whenRealtimeSyncs(proxyData.realtime, cb);
}
};
if (oldFo && typeof oldFo.migrate === "function") {
oldFo.migrate(onMigrated);
} else {
console.log("oldFo.migrate is not a function");
onMigrated();
}
return;
}
if (typeof cb === "function") {
cb();
}
};
Crypt.get(fsHash, todo);
};
return exp;
};
if (module.exports) {
module.exports = factory(requireCryptget(), requireUserObject(), requireCommonHash(), requireCommonRealtime());
}
})();
})(mergeDrive);
return mergeDrive.exports;
}
var require$$15 = getAugmentedNamespace(account);
const onCacheReadyEvt = commonUtilExports.mkEvent(true);
const onReadyEvt = commonUtilExports.mkEvent(true);
const onDisconnectEvt = commonUtilExports.mkEvent();
const onReconnectEvt = commonUtilExports.mkEvent();
const init = config => {
var _a;
const {broadcast, store, account} = config;
const drive = store.drive = store.drive || {};
let data = (_a = store.proxy) === null || _a === void 0 ? void 0 : _a.drive;
console.error(data, store.proxy);
(data === null || data === void 0 ? void 0 : data.hash) || commonHashExports.createRandomHash("drive");
if (!data.hash) {
drive.proxy = data;
account.onAccountCacheReady((() => {
onCacheReadyEvt.fire();
}));
account.onAccountReady((() => {
onReadyEvt.fire();
}));
return {
channel: "",
onDriveCacheReady: onCacheReadyEvt.reg,
onDriveReady: onReadyEvt.reg,
onDisconnect: onDisconnectEvt.reg,
onReconnect: onReconnectEvt.reg
};
}
throw new Error("NOT IMPLEMENTED");
};
const Drive = {
init
};
var drive = Object.freeze({
__proto__: null,
Drive
});
var require$$16 = getAugmentedNamespace(drive);
var cursor$1 = {
exports: {}
};
var hasRequiredCursor;
function requireCursor() {
if (hasRequiredCursor) return cursor$1.exports;
hasRequiredCursor = 1;
(function(module) {
(() => {
const factory = (Util, Constants, Messages = {}, AppConfig = {}, Crypto) => {
var Cursor = {};
Cursor.setCustomize = data => {
Messages = data.Messages;
AppConfig = data.AppConfig;
};
var DEGRADED = AppConfig.degradedLimit || 8;
var convertToUint8 = function(obj) {
var l = Object.keys(obj).length;
var u = new Uint8Array(l);
for (var i = 0; i < l; i++) {
u[i] = obj[i];
}
return u;
};
var sendMyCursor = function(ctx, clientId) {
var client = ctx.clients[clientId];
if (!client || !client.cursor) {
return;
}
var chan = ctx.channels[client.channel];
if (!chan) {
return;
}
if (chan.degraded) {
return;
}
if (!chan.sendMsg) {
return;
}
var data = {
id: client.id,
cursor: client.cursor
};
chan.sendMsg(JSON.stringify(data));
ctx.emit("MESSAGE", data, chan.clients.filter((function(cl) {
return cl !== clientId;
})));
};
var sendOurCursors = function(ctx, chan) {
if (chan.degraded) {
return;
}
chan.clients.forEach((function(c) {
var client = ctx.clients[c];
if (!client) {
return;
}
var data = {
id: client.id,
cursor: client.cursor
};
chan.sendMsg(JSON.stringify(data));
}));
};
var updateDegraded = function(ctx, wc, chan) {
var m = wc.members;
chan.degraded = m.length - 1 >= DEGRADED;
ctx.emit("DEGRADED", {
degraded: chan.degraded
}, chan.clients);
};
var initCursor = function(ctx, obj, client, cb) {
var channel = obj.channel;
var secret = obj.secret;
if (secret.keys.cryptKey) {
secret.keys.cryptKey = convertToUint8(secret.keys.cryptKey);
}
var padChan = secret.channel;
var network = ctx.store.network;
var first = true;
var c = ctx.clients[client];
if (!c) {
c = ctx.clients[client] = {
channel,
cursor: {}
};
} else {
return void cb();
}
var chan = ctx.channels[channel];
if (chan) {
if (!c.id) {
c.id = chan.wc.myID + "-" + client;
}
chan.clients.forEach((function(cl) {
var clientObj = ctx.clients[cl];
if (chan.degraded) {
return;
}
if (!clientObj) {
return;
}
ctx.emit("MESSAGE", {
id: clientObj.id,
cursor: clientObj.cursor
}, [ client ]);
}));
chan.sendMsg(JSON.stringify({
join: true,
id: c.id
}));
chan.clients.push(client);
updateDegraded(ctx, chan.wc, chan);
return void cb();
}
var onOpen = function(wc) {
ctx.channels[channel] = ctx.channels[channel] || {};
var chan = ctx.channels[channel];
chan.padChan = padChan;
if (!c.id) {
c.id = wc.myID + "-" + client;
}
if (chan.clients) {
chan.clients.forEach((function(cl) {
if (ctx.clients[cl] && !ctx.clients[cl].id) {
ctx.clients[cl].id = wc.myID + "-" + cl;
}
}));
}
if (!chan.encryptor) {
chan.encryptor = Crypto.createEncryptor(secret.keys);
}
wc.on("join", (function() {
sendOurCursors(ctx, chan);
updateDegraded(ctx, wc, chan);
}));
wc.on("leave", (function(peer) {
ctx.emit("MESSAGE", {
leave: true,
id: peer
}, chan.clients);
updateDegraded(ctx, wc, chan);
}));
wc.on("message", (function(cryptMsg) {
if (chan.degraded) {
return;
}
var msg = chan.encryptor.decrypt(cryptMsg, secret.keys && secret.keys.validateKey);
var parsed;
try {
parsed = JSON.parse(msg);
if (parsed && parsed.join) {
return void sendOurCursors(ctx, chan);
}
ctx.emit("MESSAGE", parsed, chan.clients);
} catch (e) {
console.error(e);
}
}));
chan.wc = wc;
chan.sendMsg = function(msg, cb) {
cb = cb || function() {};
var cmsg = chan.encryptor.encrypt(msg);
wc.bcast(cmsg).then((function() {
cb();
}), (function(err) {
cb({
error: err
});
}));
};
if (!first) {
return;
}
chan.clients = [ client ];
first = false;
cb();
updateDegraded(ctx, wc, chan);
};
network.join(channel).then(onOpen, (function(err) {
return void cb({
error: err
});
}));
var onReconnect = function() {
if (!ctx.channels[channel]) {
console.log("cant reconnect", channel);
return;
}
network.join(channel).then(onOpen, (function(err) {
console.error(err);
}));
};
ctx.channels[channel] = ctx.channels[channel] || {};
ctx.channels[channel].onReconnect = onReconnect;
network.on("reconnect", onReconnect);
};
var updateCursor = function(ctx, data, client, cb) {
var c = ctx.clients[client];
if (!c) {
return void cb({
error: "NO_CLIENT"
});
}
var proxy = ctx.store.proxy || {};
data.color = Util.find(proxy, [ "settings", "general", "cursor", "color" ]);
data.name = proxy[Constants.displayNameKey] || ctx.store.noDriveName || Messages.anonymous;
data.avatar = Util.find(proxy, [ "profile", "avatar" ]);
data.uid = Util.find(proxy, [ "uid" ]) || ctx.store.noDriveUid;
c.cursor = data;
sendMyCursor(ctx, client);
cb();
};
var leaveChannel = function(ctx, padChan) {
Object.keys(ctx.channels).some((function(cursorChan) {
var channel = ctx.channels[cursorChan];
if (channel.padChan !== padChan) {
return;
}
if (channel.wc) {
channel.wc.leave();
}
if (channel.onReconnect) {
var network = ctx.store.network;
network.off("reconnect", channel.onReconnect);
}
delete ctx.channels[cursorChan];
return true;
}));
};
var removeClient = function(ctx, clientId) {
var filter = function(c) {
return c !== clientId;
};
var chan;
for (var k in ctx.channels) {
chan = ctx.channels[k];
chan.clients = chan.clients.filter(filter);
if (chan.clients.length === 0) {
if (chan.wc) {
chan.wc.leave();
}
if (chan.onReconnect) {
var network = ctx.store.network;
network.off("reconnect", chan.onReconnect);
}
delete ctx.channels[k];
}
}
if (ctx.clients[clientId]) {
var leaveMsg = {
leave: true,
id: ctx.clients[clientId].id
};
chan = ctx.channels[ctx.clients[clientId].channel];
if (chan) {
chan.sendMsg(JSON.stringify(leaveMsg));
ctx.emit("MESSAGE", leaveMsg, chan.clients);
}
}
delete ctx.clients[clientId];
};
Cursor.init = function(cfg, waitFor, emit) {
var cursor = {};
if (cfg.store && cfg.store.modules && cfg.store.modules["cursor"]) {
return cfg.store.modules["cursor"];
}
var ctx = {
store: cfg.store,
emit,
channels: {},
clients: {}
};
cursor.removeClient = function(clientId) {
removeClient(ctx, clientId);
};
cursor.leavePad = function(padChan) {
leaveChannel(ctx, padChan);
};
cursor.execCommand = function(clientId, obj, cb) {
var cmd = obj.cmd;
var data = obj.data;
if (cmd === "INIT_CURSOR") {
return void initCursor(ctx, data, clientId, cb);
}
if (cmd === "UPDATE") {
return void updateCursor(ctx, data, clientId, cb);
}
};
return cursor;
};
return Cursor;
};
if (module.exports) {
module.exports = factory(requireCommonUtil(), requireCommonConstants(), undefined, undefined, requireCrypto());
}
})();
})(cursor$1);
return cursor$1.exports;
}
var support$1 = {
exports: {}
};
var hasRequiredSupport;
function requireSupport() {
if (hasRequiredSupport) return support$1.exports;
hasRequiredSupport = 1;
(function(module) {
(() => {
const factory = (ApiConfig = {}, Util, Hash, Realtime, Pinpad, Crypt, nThen, Crypto, Listmap, ChainPad, CpNetflux) => {
var Support = {};
Support.setCustomize = data => {
ApiConfig = data.ApiConfig;
};
var Nacl = Crypto.Nacl;
var notifyClient = function(ctx, admin, type, channel) {
let notifyList = Object.keys(ctx.clients).filter((cId => Boolean(ctx.clients[cId].admin) === admin));
if (!notifyList.length) {
return;
}
ctx.emit(type, {
channel
}, [ notifyList ]);
};
var getKeys = function(ctx, isAdmin, data, _cb) {
var cb = Util.mkAsync(_cb);
if (isAdmin && !ctx.adminRdyEvt) {
return void cb("EFORBIDDEN");
}
let origin = ApiConfig.httpUnsafeOrigin;
Util.fetchApi(origin, "config", true, (NewConfig => {
ctx.moderatorKeys = NewConfig.moderatorKeys;
ctx.adminKeys = NewConfig.adminKeys;
var supportKey = NewConfig.supportMailboxKey;
if (!supportKey) {
return void cb("E_NOT_INIT");
}
if (isAdmin && Util.find(ctx.store.proxy, [ "mailboxes", "supportteam", "keys", "curvePublic" ]) !== supportKey) {
return void cb("EFORBIDDEN");
}
if (isAdmin) {
return ctx.adminRdyEvt.reg((() => {
cb(null, {
supportKey,
myCurve: data.adminCurvePrivate || Util.find(ctx.store.proxy, [ "mailboxes", "supportteam", "keys", "curvePrivate" ]),
theirPublic: data.curvePublic,
notifKey: data.curvePublic
});
}));
}
cb(null, {
supportKey,
myCurve: ctx.store.proxy.curvePrivate,
theirPublic: data.curvePublic || supportKey,
notifKey: supportKey
});
}));
};
var getContent = function(ctx, data, isAdmin, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var theirPublic, myCurve;
nThen((waitFor => {
getKeys(ctx, isAdmin, data, waitFor(((err, obj) => {
if (err) {
waitFor.abort();
return void cb({
error: err
});
}
theirPublic = obj.theirPublic;
myCurve = obj.myCurve;
})));
})).nThen((() => {
var keys = Crypto.Curve.deriveKeys(theirPublic, myCurve);
var crypto = Crypto.Curve.createEncryptor(keys);
var cfg = {
network: ctx.store.network,
channel: data.channel,
noChainPad: true,
crypto,
owners: []
};
var all = [];
var cpNf;
var close = function() {
if (!cpNf) {
return;
}
if (typeof cpNf.stop !== "function") {
return;
}
cpNf.stop();
};
cb = Util.both(close, cb);
cfg.onMessage = function(msg, user, vKey, isCp, hash, author, data) {
var time = data && data.time;
try {
msg = JSON.parse(msg);
} catch (e) {
console.error(e);
return;
}
msg.time = time;
if (author) {
msg.author = author;
}
all.push(msg);
};
cfg.onError = cb;
cfg.onChannelError = cb;
cfg.onReady = function() {
cb(null, all);
};
cpNf = CpNetflux.start(cfg);
}));
};
var makeTicket = function(ctx, data, isAdmin, cb) {
var mailbox = Util.find(ctx, [ "store", "mailbox" ]);
var anonRpc = Util.find(ctx, [ "store", "anon_rpc" ]);
if (!mailbox) {
return void cb({
error: "E_NOT_READY"
});
}
if (!anonRpc) {
return void cb({
error: "anonymous rpc session not ready"
});
}
var channel = data.channel;
var title = data.title;
var ticket = data.ticket;
var supportKey, theirPublic, myCurve;
var time = +new Date;
nThen((waitFor => {
getKeys(ctx, isAdmin, data, waitFor(((err, obj) => {
if (err) {
waitFor.abort();
return void cb({
error: err
});
}
supportKey = obj.supportKey;
theirPublic = obj.theirPublic;
myCurve = obj.myCurve;
})));
})).nThen((waitFor => {
var keys = Crypto.Curve.deriveKeys(theirPublic, myCurve);
var crypto = Crypto.Curve.createEncryptor(keys);
var text = JSON.stringify(ticket);
var ciphertext = crypto.encrypt(text);
anonRpc.send("WRITE_PRIVATE_MESSAGE", [ channel, ciphertext ], waitFor(((err, res) => {
if (err) {
waitFor.abort();
return void cb({
error: err
});
}
time = res && res[0];
})));
})).nThen((waitFor => {
if (!isAdmin) {
return;
}
var doc = ctx.adminDoc.proxy;
var active = doc.tickets.active;
if (active[channel]) {
waitFor.abort();
return void cb({
error: "EEXISTS"
});
}
active[channel] = {
title: ticket.title,
restored: ticket.legacy,
premium: false,
time,
author: data.name,
supportKey,
lastAdmin: true,
authorKey: data.curvePublic,
notifications: data.notifications
};
})).nThen((waitFor => {
if (isAdmin) {
return;
}
ctx.supportData[channel] = {
time: +new Date,
title,
curvePublic: supportKey
};
ctx.Store.onSync(null, waitFor());
})).nThen((() => {
var notifChannel = isAdmin ? data.notifications : Hash.getChannelIdFromKey(supportKey);
mailbox.sendTo("NEW_TICKET", {
title,
channel,
time,
isAdmin,
supportKey,
premium: isAdmin ? "" : Util.find(ctx, [ "store", "account", "plan" ]),
user: Util.find(data.ticket, [ "sender", "curvePublic" ]) ? undefined : {
supportTeam: true
}
}, {
channel: notifChannel,
curvePublic: theirPublic
}, (obj => {
console.error(obj);
if (obj && obj.error) {
delete ctx.supportData[channel];
}
cb(obj);
}));
mailbox.sendTo("NOTIF_TICKET", {
title,
channel,
time,
isAdmin,
isNewTicket: true,
user: Util.find(data.ticket, [ "sender", "curvePublic" ]) ? undefined : {
supportTeam: true
}
}, {
channel: notifChannel,
curvePublic: theirPublic
}, (() => {}));
}));
};
var replyTicket = function(ctx, data, isAdmin, cb) {
var mailbox = Util.find(ctx, [ "store", "mailbox" ]);
var anonRpc = Util.find(ctx, [ "store", "anon_rpc" ]);
if (!mailbox) {
return void cb("E_NOT_READY");
}
if (!anonRpc) {
return void cb("anonymous rpc session not ready");
}
if (!data?.ticket) {
return void cb("E_NO_DATA");
}
var theirPublic, myCurve, notifKey;
var time;
nThen((waitFor => {
getKeys(ctx, isAdmin, data, waitFor(((err, obj) => {
if (err) {
waitFor.abort();
return void cb(err);
}
theirPublic = obj.theirPublic;
myCurve = obj.myCurve;
notifKey = obj.notifKey;
})));
})).nThen((waitFor => {
var keys = Crypto.Curve.deriveKeys(theirPublic, myCurve);
var crypto = Crypto.Curve.createEncryptor(keys);
var text = JSON.stringify(data.ticket);
var ciphertext = crypto.encrypt(text);
anonRpc.send("WRITE_PRIVATE_MESSAGE", [ data.channel, ciphertext ], waitFor(((err, res) => {
if (err) {
waitFor.abort();
return void cb(err);
}
time = res && res[0];
cb(void 0, time);
})));
})).nThen((() => {
var notifChannel = isAdmin ? data.notifChannel : Hash.getChannelIdFromKey(notifKey);
if (!notifChannel) {
return;
}
mailbox.sendTo("NOTIF_TICKET", {
isAdmin,
title: data.ticket.title,
isClose: data.ticket.close,
channel: data.channel,
time,
user: Util.find(data.ticket, [ "sender", "curvePublic" ]) ? undefined : {
supportTeam: true
}
}, {
channel: notifChannel,
curvePublic: notifKey
}, (() => {}));
}));
};
var getPinList = function(ctx) {
if (!ctx.adminDoc || !ctx.supportRpc) {
return;
}
let adminChan = ctx.adminDoc.metadata && ctx.adminDoc.metadata.channel;
let doc = ctx.adminDoc.proxy;
let t = doc.tickets;
let list = [ adminChan, ...Object.keys(t.active), ...Object.keys(t.pending), ...Object.keys(t.closed) ];
return Util.deduplicateString(list).sort();
};
var initAdminRpc = function(ctx, _cb) {
let cb = Util.mkAsync(_cb);
let proxy = ctx.store.proxy;
let curvePrivate = Util.find(proxy, [ "mailboxes", "supportteam", "keys", "curvePrivate" ]);
if (!curvePrivate) {
return void cb("EFORBIDDEN");
}
let edPrivate, edPublic;
try {
let pair = Nacl.sign.keyPair.fromSeed(Nacl.util.decodeBase64(curvePrivate));
edPrivate = Nacl.util.encodeBase64(pair.secretKey);
edPublic = Nacl.util.encodeBase64(pair.publicKey);
} catch (e) {
return void cb(e);
}
Pinpad.create(ctx.store.network, {
edPublic,
edPrivate
}, ((e, call) => {
if (e) {
return void cb(e);
}
console.log("Support RPC ready, public key is ", edPublic);
ctx.supportRpc = call;
cb();
}));
};
var loadAdminDoc = function(ctx, hash, cb) {
var secret = Hash.getSecrets("support", hash);
var listmapConfig = {
data: {},
channel: secret.channel,
crypto: Crypto.createEncryptor(secret.keys),
userName: "support",
ChainPad,
classic: true,
network: ctx.store.network,
metadata: {
validateKey: secret.keys.validateKey || undefined
}
};
var rt = ctx.adminDoc = Listmap.create(listmapConfig);
rt.proxy.on("ready", (function() {
var doc = rt.proxy;
doc.tickets = doc.tickets || {};
doc.tickets.active = doc.tickets.active || {};
doc.tickets.closed = doc.tickets.closed || {};
doc.tickets.pending = doc.tickets.pending || {};
ctx.adminRdyEvt.fire();
cb();
if (!ctx.supportRpc) {
return;
}
let list = getPinList(ctx);
let local = Hash.hashChannelList(list);
ctx.supportRpc.getServerHash((function(e, hash) {
if (e) {
return void console.warn(e);
}
if (hash !== local) {
ctx.supportRpc.reset(list, (function(e) {
if (e) {
console.warn(e);
}
}));
}
}));
}));
rt.proxy.on("change", [ "recorded" ], (function() {
notifyClient(ctx, true, "RECORDED_CHANGE", "");
}));
rt.proxy.on("remove", [ "recorded" ], (function() {
notifyClient(ctx, true, "RECORDED_CHANGE", "");
}));
};
var initializeSupportAdmin = function(ctx, isReset, waitFor) {
let unlock = waitFor();
let proxy = ctx.store.proxy;
let supportKey = Util.find(proxy, [ "mailboxes", "supportteam", "keys", "curvePublic" ]);
let privateKey = Util.find(proxy, [ "mailboxes", "supportteam", "keys", "curvePrivate" ]);
if (!isReset) {
ctx.adminRdyEvt = Util.mkEvent(true);
}
nThen((waitFor => {
getKeys(ctx, false, {}, waitFor(((err, obj) => {
setTimeout(unlock);
if (err) {
return void waitFor.abort();
}
if (obj.theirPublic !== supportKey) {
try {
delete proxy.mailboxes.supportteam;
ctx.store.mailbox.close("supportteam");
} catch (e) {}
delete ctx.adminRdyEvt;
return void waitFor.abort();
}
})));
})).nThen((waitFor => {
initAdminRpc(ctx, waitFor((err => {
if (err) {
console.error("Support RPC not ready", err);
}
})));
})).nThen((waitFor => {
let seed = privateKey.slice(0, 24);
let hash = Hash.getEditHashFromKeys({
version: 2,
type: "support",
keys: {
editKeyStr: seed
}
});
loadAdminDoc(ctx, hash, waitFor());
})).nThen((() => {
console.log("Support admin loaded");
}));
};
var getMyTickets = function(ctx, data, cId, cb) {
var all = [];
var n = nThen;
if (!ctx.clients[cId]) {
ctx.clients[cId] = {
admin: false
};
}
Object.keys(ctx.supportData).forEach((function(ticket) {
n = n((waitFor => {
var t = Util.clone(ctx.supportData[ticket]);
getContent(ctx, {
channel: ticket,
curvePublic: t.curvePublic
}, false, waitFor(((err, messages) => {
if (err) {
if (err.type === "EDELETED") {
delete ctx.supportData[ticket];
return;
}
t.error = err;
} else {
t.messages = messages;
if (messages.length && messages[messages.length - 1].close) {
ctx.supportData[ticket].closed = true;
t.closed = true;
}
}
t.id = ticket;
all.push(t);
})));
})).nThen;
}));
n((() => {
all.sort(((t1, t2) => {
if (t1.closed && t2.closed) {
return t1.time - t2.time;
}
if (t1.closed) {
return 1;
}
if (t2.closed) {
return -1;
}
return t1.time - t2.time;
}));
cb({
tickets: all
});
}));
};
var makeMyTicket = function(ctx, data, cId, cb) {
makeTicket(ctx, data, false, cb);
};
var replyMyTicket = function(ctx, data, cId, cb) {
replyTicket(ctx, data, false, (err => {
if (err) {
return void cb({
error: err
});
}
cb({
sent: true
});
}));
};
var closeMyTicket = function(ctx, data, cId, cb) {
replyTicket(ctx, data, false, (err => {
if (err) {
return void cb({
error: err
});
}
cb({
closed: true
});
}));
};
var deleteMyTicket = function(ctx, data, cId, cb) {
let support = ctx.supportData;
let channel = data.channel;
if (!support[channel] || !support[channel].closed) {
return void cb({
error: "ENOTCLOSED"
});
}
delete support[channel];
cb({
deleted: true
});
};
var listTicketsAdmin = function(ctx, data, cId, cb) {
if (!ctx.adminRdyEvt) {
return void cb({
error: "EFORBIDDEN"
});
}
if (!ctx.clients[cId]) {
ctx.clients[cId] = {
admin: true
};
}
ctx.adminRdyEvt.reg((() => {
var doc = ctx.adminDoc.proxy;
if (data.type === "pending") {
return cb(Util.clone(doc.tickets.pending));
}
if (data.type === "closed") {
return cb(Util.clone(doc.tickets.closed));
}
cb(Util.clone(doc.tickets.active));
}));
};
var loadTicketAdmin = function(ctx, data, cId, cb) {
let supportKey = data.supportKey;
ctx.adminRdyEvt.reg((() => {
let doc = ctx.adminDoc.proxy;
if (doc.oldKeys && doc.oldKeys[supportKey]) {
data.adminCurvePrivate = doc.oldKeys[supportKey].curvePrivate;
}
getContent(ctx, data, true, (function(err, res) {
if (err) {
return void cb({
error: err
});
}
var doc = ctx.adminDoc.proxy;
if (!Array.isArray(res) || !res.length) {
return void cb(res);
}
res.sort(((t1, t2) => t1.time - t2.time));
let last = res[res.length - 1];
let premium = res.some((msg => {
let curve = Util.find(msg, [ "sender", "curvePublic" ]);
if (data.curvePublic !== curve) {
return;
}
return Util.find(msg, [ "sender", "quota", "plan" ]);
}));
var entry = doc.tickets.active[data.channel];
if (entry) {
if (last.legacy) {
let lastMsg = Array.isArray(last.messages) && last.messages[last.messages.length - 1];
last = lastMsg;
}
entry.time = last.time;
entry.premium = premium;
if (last.sender) {
entry.lastAdmin = !last.sender.blockLocation;
}
if (last.close) {
doc.tickets.closed[data.channel] = entry;
delete doc.tickets.active[data.channel];
notifyClient(ctx, true, "UPDATE_TICKET", data.channel);
}
}
cb(res);
}));
}));
};
var makeTicketAdmin = function(ctx, data, cId, cb) {
if (!ctx.adminRdyEvt) {
return void cb({
error: "EFORBIDDEN"
});
}
ctx.adminRdyEvt.reg((() => {
makeTicket(ctx, data, true, cb);
}));
};
var replyTicketAdmin = function(ctx, data, cId, cb) {
if (!ctx.adminRdyEvt) {
return void cb({
error: "EFORBIDDEN"
});
}
let supportKey = data.supportKey;
ctx.adminRdyEvt.reg((() => {
let doc = ctx.adminDoc.proxy;
if (doc.oldKeys && doc.oldKeys[supportKey]) {
data.adminCurvePrivate = doc.oldKeys[supportKey].curvePrivate;
}
replyTicket(ctx, data, true, ((err, time) => {
if (err) {
return void cb({
error: err
});
}
var doc = ctx.adminDoc.proxy;
var entry = doc.tickets.active[data.channel] || doc.tickets.pending[data.channel];
entry.time = time;
entry.lastAdmin = true;
cb({
sent: true
});
}));
}));
};
var closeTicketAdmin = function(ctx, data, cId, cb) {
if (!ctx.adminRdyEvt) {
return void cb({
error: "EFORBIDDEN"
});
}
let supportKey = data.supportKey;
ctx.adminRdyEvt.reg((() => {
let doc = ctx.adminDoc.proxy;
if (doc.oldKeys && doc.oldKeys[supportKey]) {
data.adminCurvePrivate = doc.oldKeys[supportKey].curvePrivate;
}
replyTicket(ctx, data, true, (err => {
if (err) {
return void cb({
error: err
});
}
var doc = ctx.adminDoc.proxy;
var entry = doc.tickets.active[data.channel] || doc.tickets.pending[data.channel];
entry.time = +new Date;
entry.lastAdmin = true;
doc.tickets.closed[data.channel] = entry;
delete doc.tickets.active[data.channel];
delete doc.tickets.pending[data.channel];
Realtime.whenRealtimeSyncs(ctx.adminDoc.realtime, (function() {
cb({
closed: true
});
}));
}));
}));
};
var moveTicketAdmin = function(ctx, data, cId, cb) {
if (!ctx.adminRdyEvt) {
return void cb({
error: "EFORBIDDEN"
});
}
let ticketId = data.channel;
let from = data.from;
let to = data.to;
ctx.adminRdyEvt.reg((() => {
let doc = ctx.adminDoc.proxy;
let fromDoc = doc.tickets[from];
let toDoc = doc.tickets[to];
if (!from || !to) {
return void cb({
error: "EINVAL"
});
}
let ticket = fromDoc[ticketId];
if (!ticket || toDoc[ticketId]) {
return void cb({
error: "CANT_MOVE"
});
}
toDoc[ticketId] = ticket;
delete fromDoc[ticketId];
Realtime.whenRealtimeSyncs(ctx.adminDoc.realtime, (function() {
cb({
moved: true
});
}));
}));
};
var getRecorded = function(ctx, data, cId, cb) {
if (!ctx.adminRdyEvt) {
return void cb({
error: "EFORBIDDEN"
});
}
ctx.adminRdyEvt.reg((() => {
let doc = ctx.adminDoc.proxy;
let recorded = doc.recorded = doc.recorded || {};
cb({
messages: Util.clone(recorded)
});
}));
};
var setRecorded = function(ctx, data, cId, cb) {
if (!ctx.adminRdyEvt) {
return void cb({
error: "EFORBIDDEN"
});
}
let id = data.id;
let content = data.content;
let remove = Boolean(data.remove);
ctx.adminRdyEvt.reg((() => {
let doc = ctx.adminDoc.proxy;
let recorded = doc.recorded = doc.recorded || {};
if (remove) {
delete recorded[id];
} else {
recorded[id] = {
content,
count: 0
};
}
Realtime.whenRealtimeSyncs(ctx.adminDoc.realtime, (function() {
cb({
done: true
});
}));
}));
};
var useRecorded = function(ctx, data, cId, cb) {
if (!ctx.adminRdyEvt) {
return void cb({
error: "EFORBIDDEN"
});
}
let id = data.id;
ctx.adminRdyEvt.reg((() => {
let doc = ctx.adminDoc.proxy;
let recorded = doc.recorded = doc.recorded || {};
let entry = recorded[id];
if (entry) {
entry.count = (entry.count || 0) + 1;
}
cb();
}));
};
var searchAdmin = (ctx, data, cId, cb) => {
if (!ctx.adminRdyEvt) {
return void cb({
error: "EFORBIDDEN"
});
}
let tags = data.tags || [];
let text = (data.text || "").toLowerCase();
ctx.adminRdyEvt.reg((() => {
let doc = ctx.adminDoc.proxy;
let t = doc.tickets;
let all = {};
let add = (id, data, category) => {
let clone = Util.clone(data);
clone.category = category;
all[id] = clone;
};
[ "active", "pending", "closed" ].some((cat => {
let tickets = t[cat];
return Object.keys(tickets).some((id => {
let ticket = tickets[id];
let hasTag = !tags.length || (ticket.tags || []).some((tag => tags.includes(tag)));
if (!hasTag) {
return;
}
let id64 = Util.hexToBase64(id).slice(0, 10);
if (text === id64) {
all = {};
add(id, ticket, cat);
return true;
}
let hasText = !text || ticket.title.toLowerCase().includes(text);
if (!hasText) {
return;
}
add(id, ticket, cat);
}));
}));
cb({
tickets: all
});
}));
};
var setTagsAdmin = (ctx, data, cId, cb) => {
if (!ctx.adminRdyEvt) {
return void cb({
error: "EFORBIDDEN"
});
}
ctx.adminRdyEvt.reg((() => {
let doc = ctx.adminDoc.proxy;
let t = doc.tickets;
let chan = data.channel;
let ticket = t.active[chan] || t.pending[chan] || t.closed[chan];
ticket.tags = data.tags || [];
Realtime.whenRealtimeSyncs(ctx.adminDoc.realtime, (function() {
let allTags = [];
[ "active", "pending", "closed" ].forEach((cat => {
let tickets = t[cat];
Object.keys(tickets).forEach((id => {
let ticket = tickets[id];
(ticket.tags || []).forEach((tag => {
if (!allTags.includes(tag)) {
allTags.push(tag);
}
}));
}));
}));
cb({
done: true,
allTags
});
}));
}));
};
var filterTagsAdmin = (ctx, data, cId, cb) => {
if (!ctx.adminRdyEvt) {
return void cb({
error: "EFORBIDDEN"
});
}
let tags = data.tags || [];
ctx.adminRdyEvt.reg((() => {
let doc = ctx.adminDoc.proxy;
let t = doc.tickets;
if (!tags.length) {
return void cb({
all: true
});
}
let all = [];
[ "active", "pending", "closed" ].forEach((cat => {
let tickets = t[cat];
Object.keys(tickets).forEach((id => {
let ticket = tickets[id];
let hasTag = (ticket.tags || []).some((tag => tags.includes(tag)));
if (!hasTag) {
all.push(id);
}
}));
}));
cb({
tickets: all
});
}));
};
var clearLegacy = function(ctx, data, cId, cb) {
let proxy = ctx.store.proxy;
ctx.store.mailbox.close("supportadmin", (function() {
delete proxy.mailboxes.supportadmin;
ctx.Store.onSync(null, (function() {
cb({
done: true
});
}));
}));
};
var dumpLegacy = function(ctx, data, cId, cb) {
let proxy = ctx.store.proxy;
let _legacy = Util.find(proxy, [ "mailboxes", "supportadmin" ]);
if (!_legacy) {
return void cb({
error: "ENOENT"
});
}
let legacy = Util.clone(_legacy);
legacy.lastKnownHash = undefined;
legacy.viewed = [];
ctx.store.mailbox.open("supportadmin", legacy, (function(contentByHash) {
ctx.store.mailbox.close("supportadmin", (function() {}));
cb(contentByHash);
}), true, {
dump: true
});
};
let findLegacy = (ctx, author, title) => {
let doc = ctx.adminDoc.proxy;
return [ "active", "pending", "closed" ].some((k => {
let all = doc.tickets[k];
return Object.keys(all).some((id => {
let ticket = all[id];
return ticket.authorKey === author && ticket.title === title && ticket.restored;
}));
}));
};
var getLegacy = function(ctx, data, cId, cb) {
let proxy = ctx.store.proxy;
let legacy = Util.find(proxy, [ "mailboxes", "supportadmin" ]);
if (!legacy) {
return void cb({
error: "ENOENT"
});
}
ctx.store.mailbox.open("supportadmin", legacy, (function(contentByHash) {
ctx.store.mailbox.close("supportadmin", (function() {}));
let c = Util.clone(contentByHash || {});
let toFilter = [];
Object.keys(c).forEach((h => {
let msg = c[h];
if (msg.type === "CLOSE") {
if (!toFilter.includes(msg.content.id)) {
toFilter.push(msg.content.id);
}
return;
}
let author = msg.author;
let title = msg.content && msg.content.title;
if (findLegacy(ctx, author, title)) {
if (!toFilter.includes(msg.content.id)) {
toFilter.push(msg.content.id);
}
}
}));
Object.keys(c).forEach((h => {
let msg = c[h];
if (msg.content && toFilter.includes(msg.content.id)) {
delete c[h];
}
}));
cb(c);
}), true, {
dump: true
});
};
var restoreLegacy = function(ctx, data, cId, cb) {
let proxy = ctx.store.proxy;
let legacy = Util.find(proxy, [ "mailboxes", "supportadmin" ]);
if (!legacy) {
return void cb({
error: "ENOENT"
});
}
if (!ctx.adminRdyEvt) {
return void cb({
error: "EFORBIDDEN"
});
}
let messages = data.messages;
let hashes = data.hashes;
let first = messages[0];
let last = messages[messages.length - 1];
if (!first) {
return void cb({
error: "EINVAL"
});
}
ctx.adminRdyEvt.reg((() => {
let ticketData = {
name: Util.find(first, [ "sender", "name" ]),
notifications: Util.find(first, [ "sender", "notifications" ]),
curvePublic: Util.find(first, [ "sender", "curvePublic" ]),
channel: Hash.createChannelId(),
title: first.title,
time: last.time,
ticket: {
legacy: true,
title: first.title,
sender: first.sender,
messages
}
};
makeTicket(ctx, ticketData, true, (obj => {
if (obj && obj.error) {
return void cb(obj);
}
hashes.forEach((hash => {
legacy.viewed.push(hash);
}));
ctx.Store.onSync(null, (function() {
cb({
done: true
});
}));
}));
}));
};
var addAdminTicket = function(ctx, data, cb) {
if (!ctx.adminRdyEvt) {
return void cb(true);
}
ctx.adminRdyEvt.reg((() => {
let supportKey;
nThen((waitFor => {
getKeys(ctx, true, data, waitFor(((err, obj) => {
if (err) {
waitFor.abort();
return void cb(true);
}
supportKey = obj.supportKey;
})));
})).nThen((() => {
var rdmTo = Math.floor(Math.random() * 2e3);
setTimeout((() => {
var doc = ctx.adminDoc.proxy;
if (doc.tickets.active[data.channel] || doc.tickets.closed[data.channel] || doc.tickets.pending[data.channel]) {
return void cb(true);
}
doc.tickets.active[data.channel] = {
title: data.title,
premium: data.premium,
time: data.time,
author: data.user && data.user.displayName,
supportKey: data.supportKey || supportKey,
authorKey: data.user && data.user.curvePublic
};
Realtime.whenRealtimeSyncs(ctx.adminDoc.realtime, (function() {
cb(true);
}));
notifyClient(ctx, true, "NEW_TICKET", data.channel);
if (ctx.supportRpc) {
ctx.supportRpc.pin([ data.channel ], (() => {}));
}
}), rdmTo);
}));
}));
};
var updateAdminTicket = function(ctx, data) {
if (!ctx.adminRdyEvt) {
return;
}
ctx.adminRdyEvt.reg((() => {
var rdmTo = Math.floor(Math.random() * 2e3);
setTimeout((() => {
var doc = ctx.adminDoc.proxy;
let t = doc.tickets.active[data.channel] || doc.tickets.pending[data.channel];
if (!t) {
return;
}
if (data.time <= t.time) {
return;
}
if (data.isClose) {
doc.tickets.closed[data.channel] = t;
delete doc.tickets.active[data.channel];
delete doc.tickets.pending[data.channel];
}
t.time = data.time;
t.lastAdmin = false;
notifyClient(ctx, true, "UPDATE_TICKET", data.channel);
}), rdmTo);
}));
};
var checkAdminTicket = function(ctx, data, cb) {
if (!ctx.adminRdyEvt) {
return void cb(true);
}
ctx.adminRdyEvt.reg((() => {
let doc = ctx.adminDoc.proxy;
let exists = doc.tickets.active[data.channel] || doc.tickets.pending[data.channel];
cb(exists);
}));
};
var addUserTicket = function(ctx, data, cb) {
if (!ctx.supportData) {
return void cb(true);
}
let channel = data.channel;
ctx.supportData[channel] = {
time: data.time,
title: data.title,
curvePublic: data.supportKey
};
ctx.Store.onSync(null, (function() {
cb(true);
}));
};
var updateUserTicket = function(ctx, data) {
notifyClient(ctx, false, "UPDATE_TICKET", data.channel);
if (data.isClose) {
let ticket = ctx.supportData[data.channel];
if (!ticket) {
return;
}
ticket.closed = true;
}
};
var updateAdminKey = (ctx, data, cb) => {
let newKey = data.supportKey;
let newKeyPub = Hash.getBoxPublicFromSecret(newKey);
let proxy = ctx.store.proxy;
const oldKey = Util.find(proxy, [ "mailboxes", "supportteam", "keys", "curvePrivate" ]);
const oldKeyPub = Util.find(proxy, [ "mailboxes", "supportteam", "keys", "curvePublic" ]);
getKeys(ctx, false, {}, ((err, obj) => {
if (err) {
return void cb(true);
}
if (newKeyPub !== obj.theirPublic) {
return void cb(true);
}
if (oldKey === newKey || oldKeyPub === newKeyPub) {
return void cb(true);
}
let mailbox = Util.find(ctx, [ "store", "mailbox" ]);
try {
if (ctx.adminDoc) {
ctx.adminDoc.stop();
}
if (mailbox) {
mailbox.close("supportteam");
}
if (ctx.supportRpc) {
ctx.supportRpc.destroy();
}
ctx.adminRdyEvt = Util.mkEvent(true);
} catch (e) {
console.error(e);
}
ctx.Store.addAdminMailbox(null, {
version: 2,
priv: newKey
}, (obj => {
if (obj && obj.error) {
return void cb(true);
}
nThen((waitFor => {
initializeSupportAdmin(ctx, true, waitFor);
ctx.adminRdyEvt.reg((() => {
notifyClient(ctx, true, "UPDATE_RIGHTS");
cb(false);
}));
}));
}));
}));
};
let updateServerKey = (ctx, curvePublic, curvePrivate, cb) => {
let edPublic;
try {
let pair = Nacl.sign.keyPair.fromSeed(Nacl.util.decodeBase64(curvePrivate));
edPublic = Nacl.util.encodeBase64(pair.publicKey);
} catch (e) {
return void cb(e);
}
ctx.Store.adminRpc(null, {
cmd: "ADMIN_DECREE",
data: [ "SET_SUPPORT_KEYS", [ curvePublic, edPublic ] ]
}, cb);
};
let getModerators = (ctx, data, cId, cb) => {
ctx.Store.adminRpc(null, {
cmd: "GET_MODERATORS",
data: {}
}, cb);
};
let rotateKeys = function(ctx, data, cId, _cb) {
let cb = Util.once(Util.mkAsync(_cb));
let oldSupportKey;
let proxy = ctx.store.proxy;
let edPublic = proxy.edPublic;
const keyPair = Nacl.box.keyPair();
const newKeyPub = Nacl.util.encodeBase64(keyPair.publicKey);
const newKey = Nacl.util.encodeBase64(keyPair.secretKey);
const oldKey = Util.find(proxy, [ "mailboxes", "supportteam", "keys", "curvePrivate" ]);
const oldKeyPub = Util.find(proxy, [ "mailboxes", "supportteam", "keys", "curvePublic" ]);
if (!newKey || !newKeyPub) {
return void cb({
error: "INVALID_KEY"
});
}
let oldAdminChan;
nThen((waitFor => {
getKeys(ctx, false, {}, waitFor(((err, obj) => {
if (err === "E_NOT_INIT") {
return;
}
if (err) {
cb({
error: err
});
return void waitFor.abort();
}
oldSupportKey = obj.theirPublic;
})));
})).nThen((waitFor => {
if (!ctx.adminKeys.includes(edPublic)) {
waitFor.abort();
return void cb({
error: "EFORBIDDEN"
});
}
})).nThen((waitFor => {
if (!oldSupportKey) {
return;
}
if (!ctx.moderatorKeys.includes(edPublic)) {
waitFor.abort();
return void cb({
error: "EINVAL"
});
}
if (oldKeyPub !== oldSupportKey) {
waitFor.abort();
return void cb({
error: "EFORBIDDEN"
});
}
})).nThen((waitFor => {
if (!oldSupportKey) {
return;
}
ctx.adminRdyEvt.reg((() => {
let oldDoc = ctx.adminDoc.proxy;
oldAdminChan = ctx.adminDoc.metadata && ctx.adminDoc.metadata.channel;
let seed = newKey.slice(0, 24);
let hash = Hash.getEditHashFromKeys({
version: 2,
type: "support",
keys: {
editKeyStr: seed
}
});
let cfg = {
network: ctx.store.network,
initialState: "{}"
};
var oldKeys = oldDoc.oldKeys = oldDoc.oldKeys || {};
oldKeys[oldKeyPub] = {
curvePrivate: oldKey,
rotatedOn: +new Date,
rotatedBy: edPublic
};
Crypt.put(hash, JSON.stringify(oldDoc), waitFor((err => {
if (err) {
waitFor.abort();
return void cb({
error: err
});
}
})), cfg);
}));
})).nThen((waitFor => {
updateServerKey(ctx, newKeyPub, newKey, waitFor((obj => {
if (obj && obj.error) {
waitFor.abort();
return void cb(obj);
}
})));
})).nThen((() => {
if (!oldSupportKey) {
return;
}
if (ctx.adminDoc) {
ctx.adminDoc.stop();
}
let mailbox = Util.find(ctx, [ "store", "mailbox" ]);
if (mailbox) {
mailbox.close("supportteam");
}
if (ctx.supportRpc) {
ctx.supportRpc.destroy();
}
ctx.adminRdyEvt = Util.mkEvent(true);
})).nThen((waitFor => {
ctx.Store.addAdminMailbox(null, {
version: 2,
priv: newKey
}, waitFor((obj => {
if (obj && obj.error) {
waitFor.abort();
if (oldSupportKey) {
return updateServerKey(ctx, oldKeyPub, oldKey, (() => void cb(obj)));
}
return void cb(obj);
}
})));
})).nThen((waitFor => {
if (!oldSupportKey) {
return;
}
let mailbox = Util.find(ctx, [ "store", "mailbox" ]);
getModerators(ctx, null, null, waitFor((obj => {
if (obj && obj.error) {
return void cb({
success: true,
noNotify: true
});
}
let all = obj && obj[0];
Object.keys(all || {}).forEach((modEdPub => {
let modData = all[modEdPub];
mailbox.sendTo("MODERATOR_NEW_KEY", {
supportKey: newKey
}, {
channel: modData.mailbox,
curvePublic: modData.curvePublic
}, (() => {}));
}));
})));
})).nThen((waitFor => {
initializeSupportAdmin(ctx, true, waitFor);
})).nThen((waitFor => {
if (!oldAdminChan) {
return;
}
ctx.Store.adminRpc(null, {
cmd: "ARCHIVE_DOCUMENT",
data: {
id: oldAdminChan,
reason: "Deprecated support pad"
}
}, waitFor());
})).nThen((() => {
cb({
success: true
});
}));
};
let disableSupport = function(ctx, data, cId, _cb) {
let cb = Util.once(Util.mkAsync(_cb));
let proxy = ctx.store.proxy;
let edPublic = proxy.edPublic;
let moderators;
nThen((waitFor => {
getKeys(ctx, false, {}, waitFor((err => {
if (err) {
cb({
error: err
});
return void waitFor.abort();
}
})));
})).nThen((waitFor => {
if (!ctx.adminKeys.includes(edPublic)) {
waitFor.abort();
return void cb({
error: "EFORBIDDEN"
});
}
})).nThen((waitFor => {
ctx.Store.adminRpc(null, {
cmd: "ARCHIVE_SUPPORT",
data: {}
}, waitFor((obj => {
if (obj && obj.error) {
waitFor.abort();
return void cb(obj);
}
})));
})).nThen((waitFor => {
ctx.Store.adminRpc(null, {
cmd: "ADMIN_DECREE",
data: [ "SET_SUPPORT_KEYS", [ "", "" ] ]
}, waitFor((function(obj) {
if (obj && obj.error) {
waitFor.abort();
return void cb(obj);
}
})));
})).nThen((waitFor => {
getModerators(ctx, null, null, waitFor((obj => {
if (!obj || obj.error) {
waitFor.abort();
return void cb();
}
moderators = obj[0] || {};
})));
})).nThen((() => {
let n = nThen;
Object.keys(moderators).forEach((ed => {
n = n((waitFor => {
ctx.Store.adminRpc(null, {
cmd: "REMOVE_MODERATOR",
data: ed
}, waitFor((obj => {
if (obj && obj.error) {
console.error("Error removing moderator data", ed, obj.error);
}
})));
})).nThen;
}));
n((() => {
cb();
}));
}));
};
var getAdminKey = function(ctx, data, cId, cb) {
let proxy = ctx.store.proxy;
let supportKey = Util.find(proxy, [ "mailboxes", "supportteam", "keys", "curvePublic" ]);
let privateKey = Util.find(proxy, [ "mailboxes", "supportteam", "keys", "curvePrivate" ]);
getKeys(ctx, false, {}, ((err, obj) => {
if (err) {
return void cb({
error: err
});
}
if (supportKey && obj.theirPublic !== supportKey) {
privateKey = undefined;
}
cb({
curvePrivate: privateKey,
curvePublic: obj.theirPublic
});
}));
};
var addModerator = function(ctx, data, cId, cb) {
let proxy = ctx.store.proxy;
var mailbox = Util.find(ctx, [ "store", "mailbox" ]);
let supportKey = Util.find(proxy, [ "mailboxes", "supportteam", "keys", "curvePublic" ]);
let privateKey = Util.find(proxy, [ "mailboxes", "supportteam", "keys", "curvePrivate" ]);
let lastKnownHash = Util.find(proxy, [ "mailboxes", "supportteam", "lastKnownHash" ]);
let edPublic = proxy.edPublic;
getKeys(ctx, false, {}, ((err, obj) => {
if (err) {
return void cb({
error: err
});
}
if (obj.theirPublic !== supportKey) {
return void cb({
error: "EFORBIDDEN"
});
}
if (!ctx.moderatorKeys.includes(edPublic)) {
return void cb({
error: "EFORBIDDEN"
});
}
mailbox.sendTo("ADD_MODERATOR", {
supportKey: privateKey,
lastKnownHash
}, {
channel: data.mailbox,
curvePublic: data.curvePublic
}, (() => {
cb();
}));
}));
};
Support.init = function(cfg, waitFor, emit) {
var support = {};
if (cfg.store && cfg.store.modules && cfg.store.modules["support"]) {
return cfg.store.modules["support"];
}
var store = cfg.store;
var proxy = store.proxy.support = store.proxy.support || {};
var ctx = {
moderatorKeys: ApiConfig.moderatorKeys,
adminKeys: ApiConfig.adminKeys,
supportData: proxy,
store: cfg.store,
Store: cfg.Store,
emit,
clients: {}
};
if (Util.find(store, [ "proxy", "mailboxes", "supportteam" ])) {
initializeSupportAdmin(ctx, false, waitFor);
}
support.ctx = ctx;
support.removeClient = function(clientId) {
delete ctx.clients[clientId];
};
support.leavePad = function() {};
support.addAdminTicket = function(content, cb) {
addAdminTicket(ctx, content, cb);
};
support.updateAdminTicket = function(content) {
updateAdminTicket(ctx, content);
};
support.updateAdminKey = function(content, cb) {
updateAdminKey(ctx, content, cb);
};
support.checkAdminTicket = function(content, cb) {
checkAdminTicket(ctx, content, cb);
};
support.addUserTicket = function(content, cb) {
addUserTicket(ctx, content, cb);
};
support.updateUserTicket = function(content) {
updateUserTicket(ctx, content);
};
support.execCommand = function(clientId, obj, cb) {
var cmd = obj.cmd;
var data = obj.data;
if (cmd === "MAKE_TICKET") {
return void makeMyTicket(ctx, data, clientId, cb);
}
if (cmd === "GET_MY_TICKETS") {
return void getMyTickets(ctx, data, clientId, cb);
}
if (cmd === "REPLY_TICKET") {
return void replyMyTicket(ctx, data, clientId, cb);
}
if (cmd === "CLOSE_TICKET") {
return void closeMyTicket(ctx, data, clientId, cb);
}
if (cmd === "DELETE_TICKET") {
return void deleteMyTicket(ctx, data, clientId, cb);
}
if (cmd === "MAKE_TICKET_ADMIN") {
return void makeTicketAdmin(ctx, data, clientId, cb);
}
if (cmd === "LIST_TICKETS_ADMIN") {
return void listTicketsAdmin(ctx, data, clientId, cb);
}
if (cmd === "LOAD_TICKET_ADMIN") {
return void loadTicketAdmin(ctx, data, clientId, cb);
}
if (cmd === "REPLY_TICKET_ADMIN") {
return void replyTicketAdmin(ctx, data, clientId, cb);
}
if (cmd === "CLOSE_TICKET_ADMIN") {
return void closeTicketAdmin(ctx, data, clientId, cb);
}
if (cmd === "MOVE_TICKET_ADMIN") {
return void moveTicketAdmin(ctx, data, clientId, cb);
}
if (cmd === "GET_RECORDED") {
return void getRecorded(ctx, data, clientId, cb);
}
if (cmd === "SET_RECORDED") {
return void setRecorded(ctx, data, clientId, cb);
}
if (cmd === "USE_RECORDED") {
return void useRecorded(ctx, data, clientId, cb);
}
if (cmd === "SEARCH_ADMIN") {
return void searchAdmin(ctx, data, clientId, cb);
}
if (cmd === "FILTER_TAGS_ADMIN") {
return void filterTagsAdmin(ctx, data, clientId, cb);
}
if (cmd === "SET_TAGS_ADMIN") {
return void setTagsAdmin(ctx, data, clientId, cb);
}
if (cmd === "GET_LEGACY") {
return void getLegacy(ctx, data, clientId, cb);
}
if (cmd === "DUMP_LEGACY") {
return void dumpLegacy(ctx, data, clientId, cb);
}
if (cmd === "CLEAR_LEGACY") {
return void clearLegacy(ctx, data, clientId, cb);
}
if (cmd === "RESTORE_LEGACY") {
return void restoreLegacy(ctx, data, clientId, cb);
}
if (cmd === "GET_PRIVATE_KEY") {
return void getAdminKey(ctx, data, clientId, cb);
}
if (cmd === "DISABLE_SUPPORT") {
return void disableSupport(ctx, data, clientId, cb);
}
if (cmd === "ROTATE_KEYS") {
return void rotateKeys(ctx, data, clientId, cb);
}
if (cmd === "ADD_MODERATOR") {
return void addModerator(ctx, data, clientId, cb);
}
cb({
error: "NOT_SUPPORTED"
});
};
return support;
};
return Support;
};
if (module.exports) {
module.exports = factory(undefined, requireCommonUtil(), requireCommonHash(), requireCommonRealtime(), requirePinpad(), requireCryptget(), requireNthen(), requireCrypto(), requireChainpadListmap(), requireChainpad_dist(), requireChainpadNetflux());
}
})();
})(support$1);
return support$1.exports;
}
var integration = {
exports: {}
};
var hasRequiredIntegration;
function requireIntegration() {
if (hasRequiredIntegration) return integration.exports;
hasRequiredIntegration = 1;
(function(module) {
(() => {
const factory = Crypto => {
var Integration = {};
var convertToUint8 = function(obj) {
var l = Object.keys(obj).length;
var u = new Uint8Array(l);
for (var i = 0; i < l; i++) {
u[i] = obj[i];
}
return u;
};
var sendMsg = function(ctx, data, client, cb) {
var c = ctx.clients[client];
if (!c) {
return void cb({
error: "NO_CLIENT"
});
}
var chan = ctx.channels[c.channel];
if (!chan) {
return void cb({
error: "NO_CHAN"
});
}
var obj = {
id: client,
msg: data.msg,
uid: data.uid
};
chan.sendMsg(JSON.stringify(obj), cb);
ctx.emit("MESSAGE", obj, chan.clients.filter((function(cl) {
return cl !== client;
})));
};
var initIntegration = function(ctx, obj, client, cb) {
var channel = obj.channel;
var secret = obj.secret;
if (secret.keys.cryptKey) {
secret.keys.cryptKey = convertToUint8(secret.keys.cryptKey);
}
var padChan = secret.channel;
var network = ctx.store.network;
var first = true;
var c = ctx.clients[client];
if (!c) {
c = ctx.clients[client] = {
channel
};
} else {
return void cb();
}
var chan = ctx.channels[channel];
if (chan) {
if (!c.id) {
c.id = chan.wc.myID + "-" + client;
}
chan.clients.push(client);
return void cb();
}
var onOpen = function(wc) {
ctx.channels[channel] = ctx.channels[channel] || {};
var chan = ctx.channels[channel];
chan.padChan = padChan;
if (!c.id) {
c.id = wc.myID + "-" + client;
}
if (chan.clients) {
chan.clients.forEach((function(cl) {
if (ctx.clients[cl] && !ctx.clients[cl].id) {
ctx.clients[cl].id = wc.myID + "-" + cl;
}
}));
}
if (!chan.encryptor) {
chan.encryptor = Crypto.createEncryptor(secret.keys);
}
wc.on("message", (function(cryptMsg) {
var msg = chan.encryptor.decrypt(cryptMsg, secret.keys && secret.keys.validateKey);
var parsed;
try {
parsed = JSON.parse(msg);
ctx.emit("MESSAGE", parsed, chan.clients);
} catch (e) {
console.error(e);
}
}));
chan.wc = wc;
chan.sendMsg = function(msg, cb) {
cb = cb || function() {};
var cmsg = chan.encryptor.encrypt(msg);
wc.bcast(cmsg).then((function() {
cb();
}), (function(err) {
cb({
error: err
});
}));
};
if (!first) {
return;
}
chan.clients = [ client ];
first = false;
cb();
};
network.join(channel).then(onOpen, (function(err) {
return void cb({
error: err
});
}));
var onReconnect = function() {
if (!ctx.channels[channel]) {
console.log("cant reconnect", channel);
return;
}
network.join(channel).then(onOpen, (function(err) {
console.error(err);
}));
};
ctx.channels[channel] = ctx.channels[channel] || {};
ctx.channels[channel].onReconnect = onReconnect;
network.on("reconnect", onReconnect);
};
var leaveChannel = function(ctx, padChan) {
Object.keys(ctx.channels).some((function(cursorChan) {
var channel = ctx.channels[cursorChan];
if (channel.padChan !== padChan) {
return;
}
if (channel.wc) {
channel.wc.leave();
}
if (channel.onReconnect) {
var network = ctx.store.network;
network.off("reconnect", channel.onReconnect);
}
delete ctx.channels[cursorChan];
return true;
}));
};
var removeClient = function(ctx, clientId) {
var filter = function(c) {
return c !== clientId;
};
var chan;
for (var k in ctx.channels) {
chan = ctx.channels[k];
chan.clients = chan.clients.filter(filter);
if (chan.clients.length === 0) {
if (chan.wc) {
chan.wc.leave();
}
if (chan.onReconnect) {
var network = ctx.store.network;
network.off("reconnect", chan.onReconnect);
}
delete ctx.channels[k];
}
}
delete ctx.clients[clientId];
};
Integration.init = function(cfg, waitFor, emit) {
var integration = {};
if (cfg.store && cfg.store.modules && cfg.store.modules["integration"]) {
return cfg.store.modules["integration"];
}
var ctx = {
store: cfg.store,
emit,
channels: {},
clients: {}
};
integration.removeClient = function(clientId) {
removeClient(ctx, clientId);
};
integration.leavePad = function(padChan) {
leaveChannel(ctx, padChan);
};
integration.execCommand = function(clientId, obj, cb) {
var cmd = obj.cmd;
var data = obj.data;
if (cmd === "INIT") {
return void initIntegration(ctx, data, clientId, cb);
}
if (cmd === "SEND") {
return void sendMsg(ctx, data, clientId, cb);
}
};
return integration;
};
return Integration;
};
if (module.exports) {
module.exports = factory(requireCrypto());
}
})();
})(integration);
return integration.exports;
}
var onlyoffice = {
exports: {}
};
var hasRequiredOnlyoffice;
function requireOnlyoffice() {
if (hasRequiredOnlyoffice) return onlyoffice.exports;
hasRequiredOnlyoffice = 1;
(function(module) {
(() => {
const factory = () => {
var OO = {};
var getHistory = function(ctx, client, cb) {
var c = ctx.clients[client];
if (!c) {
return void cb({
error: "ENOENT"
});
}
var chan = ctx.channels[c.channel];
if (!chan) {
return void cb({
error: "ENOCHAN"
});
}
cb();
chan.history.forEach((function(msg) {
ctx.emit("MESSAGE", {
msg,
validateKey: chan.validateKey
}, [ client ]);
}));
ctx.emit("HISTORY_SYNCED", {}, [ client ]);
};
var openChannel = function(ctx, obj, client, cb) {
var channel = obj.channel;
var padChan = obj.padChan;
var network = ctx.store.network;
var first = true;
var c = ctx.clients[client];
if (!c) {
c = ctx.clients[client] = {
channel
};
} else {
return void cb();
}
var chan = ctx.channels[channel];
if (chan) {
if (!c.id) {
c.id = chan.wc.myID + "-" + client;
}
getHistory(ctx, client, (function() {
ctx.emit("READY", chan.clients, [ client ]);
}));
chan.clients.push(client);
return void cb();
}
var txid = Math.floor(Math.random() * 1e6);
var onOpen = function(wc) {
ctx.channels[channel] = ctx.channels[channel] || {
history: [],
validateKey: obj.validateKey
};
chan = ctx.channels[channel];
chan.padChan = padChan;
if (!c.id) {
c.id = wc.myID + "-" + client;
}
if (chan.clients) {
chan.clients.forEach((function(cl) {
if (ctx.clients[cl]) {
ctx.clients[cl].id = wc.myID + "-" + cl;
}
}));
}
wc.on("join", (function() {}));
wc.on("leave", (function() {}));
wc.on("message", (function(msg) {
chan.history.push(msg);
ctx.emit("MESSAGE", {
msg,
validateKey: chan.validateKey
}, chan.clients);
}));
chan.wc = wc;
chan.sendMsg = function(msg, cb) {
cb = cb || function() {};
var hash = msg.slice(0, 64);
wc.bcast(msg).then((function() {
chan.history.push(msg);
chan.lastKnownHash = hash;
cb();
}), (function(err) {
cb({
error: err
});
}));
};
if (first) {
chan.clients = [ client ];
chan.lastCpHash = obj.lastCpHash;
first = false;
cb();
}
var hk = network.historyKeeper;
var cfg = {
txid,
lastKnownHash: chan.lastKnownHash || chan.lastCpHash,
metadata: {
validateKey: obj.validateKey,
owners: obj.owners,
expire: obj.expire
}
};
var msg = [ "GET_HISTORY", wc.id, cfg ];
if (hk) {
network.sendto(hk, JSON.stringify(msg)).then((function() {}), (function(err) {
console.error(err);
}));
}
};
network.on("message", (function(msg, sender) {
if (!ctx.channels[channel]) {
return;
}
var hk = network.historyKeeper;
if (sender !== hk) {
return;
}
var parsed;
try {
parsed = JSON.parse(msg);
} catch (e) {}
if (!parsed) {
return;
}
if (parsed.txid && parsed.txid !== txid) {
return;
}
if (parsed.channel && parsed.channel !== channel) {
return;
}
if (parsed.validateKey && parsed.channel) {
if (!chan.validateKey) {
chan.validateKey = parsed.validateKey;
}
return;
}
if (parsed.state && parsed.state === 1 && parsed.channel) {
ctx.emit("READY", chan.clients, chan.clients);
return;
}
if (parsed.error && parsed.channel) {
return;
}
if (Array.isArray(parsed) && parsed[0] && parsed[0] !== txid) {
return;
}
msg = parsed[4];
if (parsed[3] !== channel) {
return;
}
var hash = msg.slice(0, 64);
if (hash === chan.lastKnownHash || hash === chan.lastCpHash) {
return;
}
chan.lastKnownHash = hash;
ctx.emit("MESSAGE", {
msg
}, chan.clients);
chan.history.push(msg);
}));
network.join(channel).then(onOpen, (function(err) {
return void cb({
error: err
});
}));
network.on("reconnect", (function() {
if (!ctx.channels[channel]) {
return;
}
network.join(channel).then(onOpen, (function(err) {
console.error(err);
}));
}));
};
var updateHash = function(ctx, data, clientId, cb) {
var c = ctx.clients[clientId];
if (!c) {
return void cb({
error: "NOT_IN_CHANNEL"
});
}
var chan = ctx.channels[c.channel];
if (!chan) {
return void cb({
error: "INVALID_CHANNEL"
});
}
var hash = data;
var index = -1;
chan.history.some((function(msg, idx) {
if (msg.slice(0, 64) === hash) {
index = idx + 1;
return true;
}
}));
if (index !== -1) {
chan.history = chan.history.slice(index);
}
cb();
};
var sendMessage = function(ctx, data, clientId, cb) {
var c = ctx.clients[clientId];
if (!c) {
return void cb({
error: "NOT_IN_CHANNEL"
});
}
var chan = ctx.channels[c.channel];
if (!chan) {
return void cb({
error: "INVALID_CHANNEL"
});
}
var _cb = function(obj) {
if (obj && obj.error) {
return void cb(obj);
}
ctx.emit("MESSAGE", {
msg: data.msg
}, chan.clients.filter((function(cl) {
return cl !== clientId;
})));
cb();
};
if (data.isCp) {
return void chan.sendMsg(data.isCp, _cb);
}
chan.sendMsg(data.msg, _cb);
};
var reencrypt = function(ctx, data, cId, cb) {
var channel = data.channel;
var network = ctx.store.network;
var onOpen = function(wc) {
var hk = network.historyKeeper;
var cfg = {
metadata: data.metadata
};
var msg = [ "GET_HISTORY", wc.id, cfg ];
network.sendto(hk, JSON.stringify(msg));
data.msgs.forEach((function(msg) {
wc.bcast(msg);
}));
wc.leave();
cb();
};
ctx.store.anon_rpc.send("IS_NEW_CHANNEL", channel, (function(e, response) {
if (e) {
return void cb({
error: e
});
}
var isNew;
if (response && response.length && typeof response[0] === "object") {
isNew = response[0].isNew;
} else {
cb({
error: "INVALID_RESPONSE"
});
}
if (!isNew) {
return void cb({
error: "EEXISTS"
});
}
network.join(channel).then(onOpen, (function(err) {
return void cb({
error: err
});
}));
}));
};
var leaveChannel = function(ctx, padChan) {
Object.keys(ctx.channels).some((function(ooChan) {
var channel = ctx.channels[ooChan];
if (channel.padChan !== padChan) {
return;
}
if (channel.wc) {
channel.wc.leave();
}
delete ctx.channels[ooChan];
return true;
}));
};
var removeClient = function(ctx, clientId) {
var filter = function(c) {
return c !== clientId;
};
var chan;
for (var k in ctx.channels) {
chan = ctx.channels[k];
chan.clients = chan.clients.filter(filter);
if (chan.clients.length === 0) {
if (chan.wc) {
chan.wc.leave();
}
delete ctx.channels[k];
}
}
if (ctx.clients[clientId]) {
var oldChannel = ctx.clients[clientId].channel;
var oldChan = ctx.channels[oldChannel];
if (oldChan) {
ctx.emit("LEAVE", {
id: clientId
}, [ oldChan.clients[0] ]);
}
delete ctx.clients[clientId];
}
};
OO.init = function(store, emit) {
var oo = {};
var ctx = {
store,
emit,
channels: {},
clients: {}
};
oo.removeClient = function(clientId) {
removeClient(ctx, clientId);
};
oo.leavePad = function(padChan) {
leaveChannel(ctx, padChan);
};
oo.execCommand = function(clientId, obj, cb) {
var cmd = obj.cmd;
var data = obj.data;
if (cmd === "SEND_MESSAGE") {
return void sendMessage(ctx, data, clientId, cb);
}
if (cmd === "UPDATE_HASH") {
return void updateHash(ctx, data, clientId, cb);
}
if (cmd === "OPEN_CHANNEL") {
return void openChannel(ctx, data, clientId, cb);
}
if (cmd === "GET_HISTORY") {
return void getHistory(ctx, clientId, cb);
}
if (cmd === "REENCRYPT") {
return void reencrypt(ctx, data, clientId, cb);
}
};
return oo;
};
return OO;
};
if (module.exports) {
module.exports = factory();
}
})();
})(onlyoffice);
return onlyoffice.exports;
}
var profile = {
exports: {}
};
var hasRequiredProfile;
function requireProfile() {
if (hasRequiredProfile) return profile.exports;
hasRequiredProfile = 1;
(function(module) {
(() => {
const factory = (Util, Hash, Constants, Realtime, Listmap, Crypto, ChainPad) => {
var Profile = {};
var initializeProfile = function(ctx, cb) {
var profile = ctx.profile;
if (!profile.edit || !profile.view) {
var hash = Hash.createRandomHash("profile");
var secret = Hash.getSecrets("profile", hash);
ctx.pinPads([ secret.channel ], (function(res) {
if (res.error) {
return void cb(res.error);
}
profile.edit = Hash.getEditHashFromKeys(secret);
profile.view = Hash.getViewHashFromKeys(secret);
setTimeout(cb);
}));
return;
}
setTimeout(cb);
};
var openChannel = function(ctx) {
var profile = ctx.profile;
var secret = Hash.getSecrets("profile", profile.edit);
var crypto = Crypto.createEncryptor(secret.keys);
var cfg = {
data: {},
network: ctx.store.network,
channel: secret.channel,
crypto,
owners: [ ctx.store.proxy.edPublic ],
ChainPad,
validateKey: secret.keys.validateKey || undefined,
userName: "profile",
classic: true
};
var lm = Listmap.create(cfg);
lm.proxy.on("create", (function() {})).on("ready", (function() {
lm.proxy.name = ctx.store.proxy[Constants.displayNameKey] || "";
ctx.listmap = lm;
if (!lm.proxy.curvePublic) {
lm.proxy.curvePublic = ctx.store.proxy.curvePublic;
}
if (!lm.proxy.notifications) {
lm.proxy.notifications = Util.find(ctx.store.proxy, [ "mailboxes", "notifications", "channel" ]);
}
if (!lm.proxy.edPublic) {
lm.proxy.edPublic = ctx.store.proxy.edPublic;
}
if (ctx.onReadyHandlers.length) {
ctx.onReadyHandlers.forEach((function(f) {
try {
f(lm.proxy);
} catch (e) {
console.error(e);
}
}));
ctx.onReadyHandlers = [];
}
})).on("change", [], (function() {
ctx.emit("UPDATE", lm.proxy, ctx.clients);
}));
};
var setName = function(ctx, value) {
ctx.listmap.proxy.name = value;
Realtime.whenRealtimeSyncs(ctx.listmap.realtime, (function() {
if (!ctx.listmap) {
return;
}
ctx.emit("UPDATE", ctx.listmap.proxy, ctx.clients);
}));
};
var subscribe = function(ctx, data, cId, cb) {
var idx = ctx.clients.indexOf(cId);
if (idx === -1) {
ctx.clients.push(cId);
}
if (ctx.listmap) {
return void cb(ctx.listmap.proxy);
}
ctx.onReadyHandlers.push((function(proxy) {
cb(proxy);
}));
};
var setValue = function(ctx, data, cId, cb) {
var key = data.key;
var value = data.value;
if (!key) {
return;
}
ctx.listmap.proxy[key] = value;
Realtime.whenRealtimeSyncs(ctx.listmap.realtime, (function() {
ctx.emit("UPDATE", ctx.listmap.proxy, ctx.clients.filter((function(clientId) {
return clientId !== cId;
})));
cb(ctx.listmap.proxy);
}));
};
var removeClient = function(ctx, cId) {
var idx = ctx.clients.indexOf(cId);
if (idx !== -1) {
ctx.clients.splice(idx, 1);
}
};
Profile.init = function(cfg, waitFor, emit) {
var profile = {};
var store = cfg.store;
if (!store.loggedIn || !store.proxy.edPublic) {
return;
}
var ctx = {
store,
pinPads: cfg.pinPads,
updateMetadata: cfg.updateMetadata,
emit,
onReadyHandlers: [],
clients: []
};
ctx.profile = store.proxy.profile = store.proxy.profile || {};
initializeProfile(ctx, waitFor((function(err) {
if (err) {
return;
}
openChannel(ctx);
})));
profile.setName = function(value) {
setName(ctx, value);
};
profile.removeClient = function(clientId) {
removeClient(ctx, clientId);
};
profile.update = function() {
if (!ctx.listmap) {
return;
}
ctx.emit("UPDATE", ctx.listmap.proxy, ctx.clients);
};
profile.execCommand = function(clientId, obj, cb) {
console.log(obj);
var cmd = obj.cmd;
var data = obj.data;
if (cmd === "SUBSCRIBE") {
return void subscribe(ctx, data, clientId, cb);
}
if (cmd === "SET") {
return void setValue(ctx, data, clientId, cb);
}
};
return profile;
};
return Profile;
};
if (module.exports) {
module.exports = factory(requireCommonUtil(), requireCommonHash(), requireCommonConstants(), requireCommonRealtime(), requireChainpadListmap(), requireCrypto(), requireChainpad_dist());
}
})();
})(profile);
return profile.exports;
}
var team = {
exports: {}
};
var roster = {
exports: {}
};
var hasRequiredRoster;
function requireRoster() {
if (hasRequiredRoster) return roster.exports;
hasRequiredRoster = 1;
(function(module) {
(function() {
var factory = function(Util, Hash, CPNetflux, Sortify, nThen, Crypto, Feedback) {
var Roster = {};
var CHECKPOINT_INTERVAL = 25;
var TIMEOUT_INTERVAL = 3e4;
var isMap = function(obj) {
return Boolean(obj && typeof obj === "object" && !Array.isArray(obj));
};
var getMessageId = function(msgString) {
return msgString.slice(0, 64);
};
var canCheckpoint = function(author, members) {
var role = Util.find(members, [ author, "role" ]);
return [ "OWNER", "ADMIN" ].indexOf(role) !== -1;
};
var isValidRole = function(role) {
return [ "OWNER", "ADMIN", "MEMBER", "VIEWER" ].indexOf(role) !== -1;
};
var isSelfDowngrade = function(author, curve, role, state) {
var selfDescribe = author === curve && state[curve];
if (!selfDescribe) {
return false;
}
var authorRole = Util.find(state, [ author, "role" ]);
if (authorRole === "MEMBER") {
return role === "VIEWER";
}
};
var canAddRole = function(author, role, members) {
var authorRole = Util.find(members, [ author, "role" ]);
if (!authorRole) {
return false;
}
if (!isValidRole(role)) {
return false;
}
if (authorRole === "OWNER") {
return true;
}
if (authorRole === "ADMIN") {
return [ "ADMIN", "MEMBER", "VIEWER" ].indexOf(role) !== -1;
}
return false;
};
var isValidId = function(id) {
return typeof id === "string" && id.length === 44;
};
var canDescribeTarget = function(author, curve, state) {
if (!state[curve]) {
return false;
}
if (author === curve && state[curve]) {
return true;
}
var authorRole = Util.find(state, [ author, "role" ]);
var targetRole = Util.find(state, [ curve, "role" ]);
if (!authorRole) {
return false;
}
if (authorRole === "OWNER") {
return true;
}
if (authorRole === "ADMIN" && targetRole !== "OWNER") {
return true;
}
return false;
};
var canRemoveRole = function(author, role, members) {
var authorRole = Util.find(members, [ author, "role" ]);
if (!authorRole) {
return false;
}
if (authorRole === "OWNER") {
return true;
}
if (authorRole === "ADMIN") {
return [ "ADMIN", "MEMBER", "VIEWER" ].indexOf(role) !== -1;
}
return false;
};
var canUpdateMetadata = function(author, members) {
var authorRole = Util.find(members, [ author, "role" ]);
return Boolean(authorRole && [ "OWNER", "ADMIN" ].indexOf(authorRole) !== -1);
};
var shouldCheckpoint = function(me, ref) {
if (!canCheckpoint(me, ref.state.members)) {
return false;
}
var since = ref.internal.sinceLastCheckpoint;
if (!since || typeof since !== "number" || since < CHECKPOINT_INTERVAL) {
return false;
}
return true;
};
var commands = Roster.commands = {};
commands.ADD = function(args, author, roster) {
if (!isMap(args)) {
throw new Error("INVALID ARGS");
}
if (!roster.internal.initialized) {
throw new Error("UNITIALIZED");
}
if (typeof roster.state.members === "undefined") {
throw new Error("CANNOT_ADD_TO_UNITIALIZED_ROSTER");
}
var members = roster.state.members;
Object.keys(args).forEach((function(curve) {
if (!isValidId(curve)) {
console.log(curve, curve.length);
throw new Error("INVALID_CURVE_KEY");
}
if (!isMap(args[curve])) {
throw new Error("INVALID_CONTENT");
}
if (members[curve]) {
throw new Error("ALREADY_PRESENT");
}
var data = args[curve];
if (typeof data.role !== "string") {
data.role = "MEMBER";
}
if (!canAddRole(author, data.role, members)) {
throw new Error("INSUFFICIENT_PERMISSIONS");
}
if (typeof data.displayName !== "string") {
throw new Error("DISPLAYNAME_REQUIRED");
}
if (typeof data.notifications !== "string") {
throw new Error("NOTIFICATIONS_REQUIRED");
}
}));
var changed = false;
Object.keys(args).forEach((function(curve) {
changed = true;
members[curve] = args[curve];
}));
return changed;
};
commands.RM = function(args, author, roster) {
if (!Array.isArray(args)) {
throw new Error("INVALID_ARGS");
}
if (typeof roster.state.members === "undefined") {
throw new Error("CANNOT_RM_FROM_UNITIALIZED_ROSTER");
}
var members = roster.state.members;
args.forEach((function(curve) {
if (!isValidId(curve)) {
throw new Error("INVALID_CURVE_KEY");
}
if (curve === author) {
return;
}
var role = members[curve].role;
if (!canRemoveRole(author, role, members)) {
throw new Error("INSUFFICIENT_PERMISSIONS");
}
}));
var changed = false;
args.forEach((function(curve) {
if (!members[curve]) {
return;
}
changed = true;
delete members[curve];
}));
return changed;
};
commands.DESCRIBE = function(args, author, roster) {
if (!args || typeof args !== "object" || Array.isArray(args)) {
throw new Error("INVALID_ARGUMENTS");
}
if (typeof roster.state.members === "undefined") {
throw new Error("NOT_READY");
}
var members = roster.state.members;
Object.keys(args).forEach((function(curve) {
if (!isValidId(curve)) {
throw new Error("INVALID_ID");
}
if (!members[curve]) {
throw new Error("NOT_PRESENT");
}
if (!canDescribeTarget(author, curve, members)) {
throw new Error("INSUFFICIENT_PERMISSIONS");
}
var data = args[curve];
if (!isMap(data)) {
throw new Error("INVALID_ARGUMENTS");
}
var current = Util.clone(members[curve]);
if (typeof data.role === "string") {
if (!isSelfDowngrade(author, curve, data.role, members) && !canAddRole(author, data.role, members)) {
throw new Error("INSUFFICIENT_PERMISSIONS");
}
}
if (typeof current.displayName !== "string" && typeof data.displayName !== "string") {
throw new Error("DISPLAYNAME_REQUIRED");
}
if ([ "undefined", "string" ].indexOf(typeof data.displayName) === -1) {
throw new Error("INVALID_DISPLAYNAME");
}
if (typeof current.notifications !== "string" && typeof data.notifications !== "string") {
throw new Error("NOTIFICATIONS_REQUIRED");
}
if ([ "undefined", "string" ].indexOf(typeof data.notifications) === -1) {
throw new Error("INVALID_NOTIFICATIONS");
}
}));
var changed = false;
Object.keys(args).forEach((function(curve) {
var current = Util.clone(members[curve]);
var data = args[curve];
Object.keys(data).forEach((function(key) {
if (typeof current[key] !== "undefined" && data[key] === null) {
return void delete current[key];
}
current[key] = data[key];
}));
if (Sortify(current) !== Sortify(members[curve])) {
changed = true;
members[curve] = current;
}
}));
return changed;
};
commands.CHECKPOINT = function(args, author, roster) {
if (!isMap(args)) {
throw new Error("INVALID_CHECKPOINT_STATE");
}
if (!roster.internal.initialized) {
roster.state = args;
var metadata = roster.state.metadata = roster.state.metadata || {};
metadata.topic = metadata.topic || "";
metadata.name = metadata.name || "";
metadata.avatar = metadata.avatar || "";
roster.internal.initialized = true;
return true;
} else if (Sortify(args) !== Sortify(roster.state)) {
throw new Error("CHECKPOINT_DOES_NOT_MATCH_PREVIOUS_STATE");
}
if (!canCheckpoint(author, roster.state.members)) {
throw new Error("INSUFFICIENT_PERMISSIONS");
}
roster.state = args;
return true;
};
var MANDATORY_METADATA_FIELDS = [ "avatar", "name", "topic" ];
commands.METADATA = function(args, author, roster) {
if (!isMap(args)) {
throw new Error("INVALID_ARGS");
}
if (!canUpdateMetadata(author, roster.state.members)) {
throw new Error("INSUFFICIENT_PERMISSIONS");
}
Object.keys(args).forEach((function(k) {
if (args[k] === null) {
if (MANDATORY_METADATA_FIELDS.indexOf(k) === -1) {
return;
}
throw new Error("CANNOT_REMOVE_MANDATORY_METADATA");
}
if (typeof args[k] !== "string") {
throw new Error("INVALID_ARGUMENTS");
}
}));
var changed = false;
Object.keys(args).forEach((function(k) {
if (typeof roster.state.metadata[k] !== "undefined" && args[k] === null) {
changed = true;
delete roster.state.metadata[k];
}
if (args[k] === roster.state.metadata[k]) {
return;
}
changed = true;
roster.state.metadata[k] = args[k];
}));
return changed;
};
commands.INVITE = function(args, author, roster) {
if (!isMap(args)) {
throw new Error("INVALID_ARGS");
}
if (!roster.internal.initialized) {
throw new Error("UNINITIALIED");
}
if (typeof roster.state.members === "undefined") {
throw new Error("CANNOT+INVITE_TO_UNINITIALIED_ROSTER");
}
var members = roster.state.members;
Object.keys(args).forEach((function(curve) {
if (!isValidId(curve)) {
console.log(curve, curve.length);
throw new Error("INVALID_CURVE_KEY");
}
if (!isMap(args[curve])) {
throw new Error("INVALID_CONTENT");
}
if (members[curve]) {
throw new Error("ARLEADY_PRESENT");
}
var data = args[curve];
if (typeof data.role !== "string") {
data.role = "VIEWER";
}
if (typeof data.pending === "undefined") {
data.pending = true;
}
if (!canAddRole(author, data.role, members)) {
throw new Error("INSUFFICIENT_PERMISSIONS");
}
if (typeof data.displayName !== "string" || !data.displayName) {
throw new Error("DISPLAYNAME_REQUIRED");
}
}));
var changed = false;
Object.keys(args).forEach((function(curve) {
changed = true;
members[curve] = args[curve];
}));
return changed;
};
commands.ACCEPT = function(args, author, roster) {
if (!roster.internal.initialized) {
throw new Error("UNINITIALIED");
}
if (typeof roster.state.members === "undefined") {
throw new Error("CANNOT_ADD_TO_UNINITIALIED_ROSTER");
}
var members = roster.state.members;
if (!isMap(members[author])) {
throw new Error("INSUFFICIENT_PERMISSIONS");
}
if (!members[author].pending) {
throw new Error("ALREADY_PRESENT");
}
if (typeof args !== "string") {
throw new Error("INVALID_ARGS");
}
if (!isValidId(args)) {
throw new Error("INVALID_CURVE_KEY");
}
var curve = args;
if (typeof members[curve] !== "undefined") {
throw new Error("MEMBER_ALREADY_PRESENT");
}
var clone = Util.clone(members[author]);
delete clone.remaining;
delete clone.totalUses;
delete clone.inviteChannel;
delete clone.previewChannel;
members[curve] = clone;
var remaining = members[author].remaining || 1;
if (remaining === -1) {
return true;
}
if (remaining > 1) {
members[author].remaining = remaining - 1;
} else {
delete members[author];
}
return true;
};
var handleCommand = function(content, author, roster) {
if (!(Array.isArray(content) && typeof author === "string")) {
throw new Error("INVALID ARGUMENTS");
}
var command = content[0];
if (typeof commands[command] !== "function") {
throw new Error("INVALID_COMMAND");
}
return commands[command](content[1], author, roster);
};
var simulate = function(content, author, roster) {
return handleCommand(content, author, Util.clone(roster));
};
Roster.create = function(config, _cb) {
if (typeof _cb !== "function") {
throw new Error("EXPECTED_CALLBACK");
}
var cb = Util.once(Util.mkAsync(_cb));
if (!config.network) {
return void cb("EXPECTED_NETWORK");
}
if (!config.channel || typeof config.channel !== "string" || config.channel.length !== 32) {
return void cb("EXPECTED_CHANNEL");
}
if (!config.keys || typeof config.keys !== "object") {
return void cb("EXPECTED_CRYPTO_KEYS");
}
if (!config.store) {
return void cb("EXPECTED_STORE");
}
var response = Util.response((function(label, info) {
console.error("ROSTER_RESPONSE__" + label, info);
}));
var store = config.store;
var keys = config.keys;
var me = keys.myCurvePublic;
var channel = config.channel;
var lastKnownHash = config.lastKnownHash || -1;
if (config.newTeam) {
lastKnownHash = undefined;
}
var ref = {
state: {
members: {},
metadata: {}
},
internal: {
initialized: false,
sinceLastCheckpoint: 0,
lastCheckpointHash: lastKnownHash
}
};
var roster = {};
var events = {
change: Util.mkEvent(),
checkpoint: Util.mkEvent()
};
roster.on = function(key, handler) {
if (typeof events[key] !== "object") {
throw new Error("unsupported event");
}
events[key].reg(handler);
return roster;
};
roster.off = function(key, handler) {
if (typeof events[key] !== "object") {
throw new Error("unsupported event");
}
events[key].unreg(handler);
return roster;
};
roster.once = function(key, handler) {
if (typeof events[key] !== "object") {
throw new Error("unsupported event");
}
var f = function() {
handler.apply(null, Array.prototype.slice.call(arguments));
events[key].unreg(f);
};
events[key].reg(f);
return roster;
};
roster.getState = function() {
return Util.clone(ref.state);
};
roster.getLastCheckpointHash = function() {
return ref.internal.lastCheckpointHash || -1;
};
var clearPendingCheckpoints = function() {
if (ref.internal.pendingCheckpointId) {
response.clear(ref.internal.pendingCheckpointId);
delete ref.internal.pendingCheckpointId;
}
clearTimeout(ref.internal.checkpointTimeout);
delete ref.internal.checkpointTimeout;
};
roster.stop = function() {
if (ref.internal.cpNetflux && typeof ref.internal.cpNetflux.stop === "function") {
ref.internal.cpNetflux.stop();
clearPendingCheckpoints();
} else {
console.log("FAILED TO LEAVE");
}
};
var ready = false;
var onCacheReady = function() {
if (!config.onCacheReady) {
return;
}
var state = ref.state;
if (!Object.keys(state.members || {}).length) {
try {
ref.internal.cpNetflux.resetCache();
} catch (e) {
console.error(e);
}
return void config.onCacheReady({
error: "CORRUPTED"
});
}
config.onCacheReady(roster);
};
var onReady = function() {
ready = true;
cb(void 0, roster);
};
var onChannelError = function(info) {
if (info && info.type === "EUNKNOWN") {
return;
}
if (!ready) {
return void cb(info);
}
console.error("CHANNEL_ERROR", info);
};
var onConnectionChange = function(info) {
if (info.state) {
return;
}
ready = false;
};
var onConnect = function() {
console.log("ROSTER CONNECTED");
};
var isReady = function() {
return Boolean(ready && me);
};
var onMessage = function(msg, user, vKey, isCp, hash, author) {
ref.internal.sinceLastCheckpoint++;
var parsed = Util.tryParse(msg);
if (!parsed) {
return void console.error("could not parse");
}
var changed;
var error;
try {
changed = handleCommand(parsed, author, ref);
} catch (err) {
error = err.message;
}
var id = getMessageId(hash);
if (response.expected(id)) {
if (error) {
return void response.handle(id, [ error ]);
}
try {
if (!changed) {
response.handle(id, [ "NO_CHANGE" ]);
console.log(msg);
} else {
response.handle(id, [ void 0, roster.getState() ]);
}
} catch (err) {
console.log("CAUGHT", err);
}
}
if (parsed[0] === "CHECKPOINT" && changed) {
if (isReady()) {
events.checkpoint.fire(hash);
}
ref.internal.sinceLastCheckpoint = 0;
ref.internal.lastCheckpointHash = hash;
} else if (changed) {
if (isReady()) {
events.change.fire();
}
}
clearPendingCheckpoints();
if (!isReady() || !shouldCheckpoint(me, ref)) {
return;
}
var delay = 1e3 * Math.floor(Math.random() * 20) + 5e3;
ref.internal.checkpointTimeout = setTimeout((function() {
ref.internal.pendingCheckpointId = roster.checkpoint((function(err) {
if (err) {
console.error(err);
}
}));
}), delay);
};
var isCacheCheckpoint = function(msg, author) {
var parsed = Util.tryParse(msg);
if (parsed[0] !== "CHECKPOINT") {
return false;
}
var changed = simulate(parsed, author, ref);
return changed;
};
var metadata, crypto;
var send = function(msg, cb) {
if (!isReady()) {
return void cb("NOT_READY");
}
var anon_rpc = store.anon_rpc;
if (!anon_rpc) {
return void cb("ANON_RPC_NOT_READY");
}
var changed = false;
try {
changed = simulate(msg, keys.myCurvePublic, ref);
} catch (err) {
return void cb(err.message);
}
if (!changed) {
return void cb("NO_CHANGE");
}
var ciphertext = crypto.encrypt(Sortify(msg));
var id = getMessageId(ciphertext);
response.expect(id, (function(err, state) {
if (err) {
return void cb(err);
}
cb(void 0, state, id);
}), TIMEOUT_INTERVAL);
anon_rpc.send("WRITE_PRIVATE_MESSAGE", [ channel, ciphertext ], (function(err) {
if (err) {
return response.handle(id, [ err.message || err ]);
}
}));
return id;
};
roster.init = function(_data, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
if (ref.internal.initialized) {
return void cb("ALREADY_INITIALIZED");
}
if (!isMap(_data)) {
return void cb("INVALID_ARGUMENTS");
}
var data = Util.clone(_data);
data.role = "OWNER";
var members = {};
members[me] = data;
send([ "CHECKPOINT", {
members
} ], cb);
};
roster.checkpoint = function(_cb) {
var cb = Util.once(Util.mkAsync(_cb));
send([ "CHECKPOINT", Util.clone(ref.state) ], cb);
};
roster.add = function(_data, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
if (!ref.internal.initialized) {
return cb("UNINITIALIZED");
}
if (!isMap(_data)) {
return void cb("INVALID_ARGUMENTS");
}
var data = Util.clone(_data);
Object.keys(data).forEach((function(curve) {
if (!isValidId(curve) || isMap(ref.state.members[curve])) {
return delete data[curve];
}
}));
send([ "ADD", data ], cb);
};
roster.remove = function(_data, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var state = ref.state;
if (!state) {
return cb("UNINITIALIZED");
}
if (!Array.isArray(_data)) {
return void cb("INVALID_ARGUMENTS");
}
var data = Util.clone(_data);
var toRemove = [];
var current = Object.keys(state.members);
data.forEach((function(curve) {
if (current.indexOf(curve) === -1) {
return;
}
toRemove.push(curve);
}));
send([ "RM", toRemove ], cb);
};
roster.describe = function(_data, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var state = ref.state;
if (!state) {
return cb("UNINITIALIZED");
}
if (!isMap(_data)) {
return void cb("INVALID_ARGUMENTS");
}
var data = Util.clone(_data);
if (Object.keys(data).some((function(curve) {
var member = data[curve];
if (!isMap(member)) {
delete data[curve];
}
if (!isMap(state.members[curve])) {
return true;
}
Object.keys(member).forEach((function(k) {
if (member[k] === state.members[curve][k]) {
delete member[k];
}
}));
}))) {
return void cb("INVALID_ARGUMENTS");
}
send([ "DESCRIBE", data ], cb);
};
roster.metadata = function(_data, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var metadata = ref.state.metadata;
if (!isMap(_data)) {
return void cb("INVALID_ARGUMENTS");
}
var data = Util.clone(_data);
Object.keys(data).forEach((function(k) {
if (data[k] === metadata[k]) {
delete data[k];
}
}));
send([ "METADATA", data ], cb);
};
roster.invite = function(_data, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var state = ref.state;
if (!state) {
return cb("UNINITIALIZED");
}
if (!ref.internal.initialized) {
return cb("UNINITIALIZED");
}
if (!isMap(_data)) {
return void cb("INVALID_ARGUMENTS");
}
var data = Util.clone(_data);
Object.keys(data).forEach((function(curve) {
if (!isValidId(curve) || isMap(ref.state.members[curve])) {
return delete data[curve];
}
}));
send([ "INVITE", data ], cb);
};
roster.accept = function(_data, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
if (typeof _data !== "string" || !isValidId(_data)) {
return void cb("INVALID_ARGUMENTS");
}
send([ "ACCEPT", _data ], cb);
};
nThen((function(w) {
if (!store.anon_rpc) {
return;
}
store.anon_rpc.send("GET_METADATA", channel, (function(err, data) {
if (err) {
w.abort();
return void console.error(err);
}
metadata = ref.internal.metadata = data && data[0] || undefined;
}));
})).nThen((function(w) {
if (!config.keys.teamEdPublic && metadata && metadata.validateKey) {
config.keys.teamEdPublic = metadata.validateKey;
}
if (!config.keys.teamEdPublic) {
w.abort();
return void cb("NO_VALIDATE_KEY");
}
try {
crypto = Crypto.Team.createEncryptor(config.keys);
} catch (err) {
w.abort();
return void cb(err);
}
})).nThen((function() {
if (typeof lastKnownHash === "string") {
console.log("Synchronizing from checkpoint");
}
ref.internal.cpNetflux = CPNetflux.start({
lastKnownHash,
network: config.network,
channel: config.channel,
crypto,
validateKey: config.keys.teamEdPublic,
owners: config.owners,
Cache: config.Cache,
isCacheCheckpoint,
onCacheReady,
onChannelError,
onReady,
onConnect,
onConnectionChange,
onMessage,
noChainPad: true
});
}));
};
return Roster;
};
if (module.exports) {
module.exports = factory(requireCommonUtil(), requireCommonHash(), requireChainpadNetflux(), requireJSON_sortify(), requireNthen(), requireCrypto());
}
})();
})(roster);
return roster.exports;
}
var invitation = {
exports: {}
};
var hasRequiredInvitation;
function requireInvitation() {
if (hasRequiredInvitation) return invitation.exports;
hasRequiredInvitation = 1;
(function(module) {
(function() {
var factory = function(Util, Cred, Nacl, Crypto) {
var Invite = {};
var encode64 = Nacl.util.encodeBase64;
var decode64 = Nacl.util.decodeBase64;
Invite.generateKeys = function() {
var ed = Nacl.sign.keyPair();
var curve = Nacl.box.keyPair();
return {
edPublic: encode64(ed.publicKey),
edPrivate: encode64(ed.secretKey),
curvePublic: encode64(curve.publicKey),
curvePrivate: encode64(curve.secretKey)
};
};
Invite.generateSignPair = function() {
var ed = Nacl.sign.keyPair();
return {
validateKey: encode64(ed.publicKey),
signKey: encode64(ed.secretKey)
};
};
var b64ToChannelKeys = function(b64) {
var dispense = Cred.dispenser(decode64(b64));
return {
channel: Util.uint8ArrayToHex(dispense(16)),
cryptKey: dispense(Nacl.secretbox.keyLength)
};
};
Invite.deriveInviteKeys = b64ToChannelKeys;
Invite.derivePreviewKeys = b64ToChannelKeys;
Invite.createRosterEntry = function(roster, data, cb) {
var toInvite = {};
toInvite[data.curvePublic] = data.content;
roster.invite(toInvite, cb);
};
var decodeUTF8 = Nacl.util.decodeUTF8;
Invite.encryptHash = function(data, seedStr) {
var array = decodeUTF8(seedStr);
var bytes = Nacl.hash(array);
var cryptKey = bytes.subarray(0, 32);
return Crypto.encrypt(data, cryptKey);
};
Invite.decryptHash = function(encryptedStr, seedStr) {
var array = decodeUTF8(seedStr);
var bytes = Nacl.hash(array);
var cryptKey = bytes.subarray(0, 32);
return Crypto.decrypt(encryptedStr, cryptKey);
};
return Invite;
};
if (module.exports) {
module.exports = factory(requireCommonUtil(), requireCommonCredential(), requireNaclFast(), requireCrypto());
}
})();
})(invitation);
return invitation.exports;
}
var hasRequiredTeam;
function requireTeam() {
if (hasRequiredTeam) return team.exports;
hasRequiredTeam = 1;
(function(module) {
(() => {
const factory = (Util, Hash, Constants, Realtime, ProxyManager, UserObject, SF, Roster, Messaging, Feedback, Invite, Crypt, Cache, Pinpad, Listmap, Crypto, CpNetflux, ChainPad, nThen, Nacl) => {
var Team = {};
Nacl = Nacl || typeof window !== "undefined" && window.nacl;
var onStoreReady = Util.mkEvent(true);
var openCachedTeamChat = function() {};
var registerChangeEvents = function(ctx, team, proxy, fId) {
if (!team) {
return;
}
if (!fId) {
proxy.on("change", [ "drive", UserObject.SHARED_FOLDERS ], (function(o, n, p) {
if (p.length > 3 && p[3] === "password") {
var id = p[2];
var data = proxy.drive[UserObject.SHARED_FOLDERS][id];
var href = team.manager.user.userObject.getHref ? team.manager.user.userObject.getHref(data) : data.href;
var parsed = Hash.parsePadUrl(href);
var secret = Hash.getSecrets(parsed.type, parsed.hash, o);
setTimeout((function() {
SF.updatePassword(ctx.Store, {
oldChannel: secret.channel,
password: n,
href
}, ctx.store.network, (function() {
console.log("Shared folder password changed");
}));
}));
return false;
}
}));
proxy.on("disconnect", (function() {
team.offline = true;
team.sendEvent("NETWORK_DISCONNECT", team.id);
}));
proxy.on("reconnect", (function() {
team.offline = false;
team.sendEvent("NETWORK_RECONNECT", team.id);
}));
}
proxy.on("change", [], (function(o, n, p) {
if (fId) {
if (p[0] === UserObject.FILES_DATA && typeof n === "object" && n.channel && !n.owners) {
var toPin = [ n.channel ];
if (n.rtChannel) {
toPin.push(n.rtChannel);
}
if (n.lastVersion) {
toPin.push(n.lastVersion);
}
team.pin(toPin, (function(obj) {
if (obj && obj.error) {
console.error(obj.error);
}
}));
}
if (p[0] === UserObject.FILES_DATA && typeof o === "object" && o.channel && !n) {
var toUnpin = [ o.channel ];
var c = team.manager.findChannel(o.channel);
var exists = c.some((function(data) {
return data.fId !== fId;
}));
if (!exists) {
if (o.rtChannel) {
toUnpin.push(o.rtChannel);
}
if (o.lastVersion) {
toUnpin.push(o.lastVersion);
}
team.unpin(toUnpin, (function(obj) {
if (obj && obj.error) {
console.error(obj);
}
}));
}
}
}
if (o && !n && Array.isArray(p) && (p[0] === UserObject.FILES_DATA || p[0] === "drive" && p[1] === UserObject.FILES_DATA)) {
setTimeout((function() {
ctx.Store.checkDeletedPad(o && o.channel);
}));
}
team.sendEvent("DRIVE_CHANGE", {
id: fId,
old: o,
new: n,
path: p
});
}));
proxy.on("remove", [], (function(o, p) {
team.sendEvent("DRIVE_REMOVE", {
id: fId,
old: o,
path: p
});
}));
};
var closeTeam = function(ctx, teamId) {
var team = ctx.teams[teamId];
if (!team) {
return;
}
try {
team.listmap.stop();
} catch (e) {}
try {
team.roster.stop();
} catch (e) {}
team.proxy = {};
team.stopped = true;
delete ctx.teams[teamId];
delete ctx.cache[teamId];
delete ctx.store.proxy.teams[teamId];
ctx.emit("LEAVE_TEAM", teamId, team.clients);
ctx.updateMetadata();
if (ctx.store.calendar) {
ctx.store.calendar.closeTeam(teamId);
}
if (ctx.store.mailbox) {
ctx.store.mailbox.close("team-" + teamId, (function() {}));
}
};
var getTeamChannelList = function(ctx, id) {
var store = ctx.teams[id];
if (!store) {
return null;
}
var list = store.manager.getChannelsList("pin");
var team = ctx.store.proxy.teams[id];
list.push(`${team.channel}#drive`);
var chatChannel = Util.find(team, [ "keys", "chat", "channel" ]);
var membersChannel = Util.find(team, [ "keys", "roster", "channel" ]);
var mailboxChannel = Util.find(team, [ "keys", "mailbox", "channel" ]);
if (chatChannel) {
list.push(chatChannel);
}
if (membersChannel) {
list.push(membersChannel);
}
if (mailboxChannel) {
list.push(mailboxChannel);
}
if (store.proxy.calendars) {
var cList = Object.keys(store.proxy.calendars).map((function(c) {
return store.proxy.calendars[c].channel;
}));
list = list.concat(cList);
}
var state = store.roster.getState();
if (state.members) {
Object.keys(state.members).forEach((function(curve) {
var m = state.members[curve];
if (m.inviteChannel && m.pending) {
list.push(m.inviteChannel);
}
if (m.previewChannel && m.pending) {
list.push(m.previewChannel);
}
}));
}
list.sort();
return list;
};
var handleSharedFolder = function(ctx, id, sfId, rt) {
var t = ctx.teams[id];
if (!t) {
return;
}
if (!rt) {
delete t.sharedFolders[sfId];
return;
}
t.sharedFolders[sfId] = rt;
registerChangeEvents(ctx, t, rt.proxy, sfId);
};
var initRpc = function(ctx, team, data, cb) {
if (team.rpc) {
return void cb();
}
if (!data.edPrivate || !data.edPublic) {
return void cb("EFORBIDDEN");
}
Pinpad.create(ctx.store.network, data, (function(e, call) {
if (e) {
return void cb(e);
}
team.rpc = call;
if (team && team.onRpcReadyEvt) {
team.onRpcReadyEvt.fire();
}
cb();
}), Cache);
};
var onCacheReady = function(ctx, id, lm, roster, keys, cId, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
if (ctx.cache[id]) {
return void cb();
}
var proxy = lm.proxy;
var team = {
id,
proxy,
listmap: lm,
clients: [],
realtime: lm.realtime,
handleSharedFolder: function(sfId, rt) {
handleSharedFolder(ctx, id, sfId, rt);
},
sharedFolders: {},
roster,
onRpcReadyEvt: Util.mkEvent(true),
offline: true
};
ctx.cache[id] = team;
if (cId) {
team.clients.push(cId);
}
roster.on("change", (function() {
var state = roster.getState();
var me = Util.find(ctx, [ "store", "proxy", "curvePublic" ]);
if (!state.members || !Object.keys(state.members).length) {
console.error(JSON.stringify(state));
return;
}
if (!state.members[me]) {
return void closeTeam(ctx, id);
}
var teamData = Util.find(ctx, [ "store", "proxy", "teams", id ]);
if (teamData) {
teamData.metadata = state.metadata;
}
ctx.updateMetadata();
ctx.emit("ROSTER_CHANGE", id, team.clients);
}));
roster.on("checkpoint", (function(hash) {
var rosterData = Util.find(ctx, [ "store", "proxy", "teams", id, "keys", "roster" ]);
rosterData.lastKnownHash = hash;
}));
team.sendEvent = function(q, data, sender) {
ctx.emit(q, data, team.clients.filter((function(cId) {
return cId !== sender;
})));
};
team.getChatData = function() {
var chatKeys = keys.chat || {};
var hash = chatKeys.edit || chatKeys.view;
if (!hash) {
return {};
}
var secret = Hash.getSecrets("chat", hash);
return {
teamId: id,
channel: secret.channel,
secret,
validateKey: chatKeys.validateKey
};
};
team.pin = function(data, cb) {
if (!keys.drive.edPrivate) {
return void cb({
error: "EFORBIDDEN"
});
}
if (!team.rpc) {
return void cb({
error: "TEAM_RPC_NOT_READY"
});
}
if (typeof cb !== "function") {
console.error("expected a callback");
}
team.rpc.pin(data, (function(e, hash) {
if (e) {
return void cb({
error: e
});
}
cb({
hash
});
}));
};
team.unpin = function(data, cb) {
if (!keys.drive.edPrivate) {
return void cb({
error: "EFORBIDDEN"
});
}
if (!team.rpc) {
return void cb({
error: "TEAM_RPC_NOT_READY"
});
}
if (typeof cb !== "function") {
console.error("expected a callback");
}
team.rpc.unpin(data, (function(e, hash) {
if (e) {
return void cb({
error: e
});
}
cb({
hash
});
}));
};
var loadSharedFolder = function(id, data, cb, isNew) {
SF.load({
isNew,
network: ctx.store.network || ctx.store.networkPromise,
store: team,
isNewChannel: ctx.Store.isNewChannel,
Store: ctx.Store
}, id, data, cb);
};
var teamData = ctx.store.proxy.teams[team.id];
var hash = teamData.hash || teamData.roHash;
var secret = Hash.getSecrets("team", hash, teamData.password);
var manager = team.manager = ProxyManager.create(proxy.drive, {
onSync: function(cb) {
ctx.Store.onSync(id, cb);
},
edPublic: keys.drive.edPublic,
pin: team.pin,
unpin: team.unpin,
loadSharedFolder,
settings: {
drive: Util.find(ctx.store, [ "proxy", "settings", "drive" ])
},
removeOwnedChannel: function(channel, cb) {
var data;
if (typeof channel === "object") {
channel.teamId = id;
data = channel;
} else {
data = {
channel,
teamId: id
};
}
ctx.Store.removeOwnedChannel("", data, cb);
},
Store: ctx.Store,
store: ctx.store
}, {
teamId: team.id,
outer: true,
edPublic: keys.drive.edPublic,
loggedIn: true,
log: function(msg) {
team.sendEvent("DRIVE_LOG", msg);
},
rt: team.realtime,
editKey: secret.keys.secondaryKey,
readOnly: Boolean(!secret.keys.secondaryKey)
});
team.secondaryKey = secret && secret.keys.secondaryKey;
team.userObject = manager.user.userObject;
nThen((function(waitFor) {
ctx.teams[id] = team;
registerChangeEvents(ctx, team, proxy);
var network = ctx.store.network || ctx.store.networkPromise;
SF.loadSharedFolders(ctx.Store, network, team, team.proxy.drive, team.userObject, waitFor, (function(data) {
ctx.progress += 70 / (ctx.numberOfTeams * data.max);
ctx.updateProgress({
progress: ctx.progress
});
}), true);
})).nThen((function() {
if (ctx.store.modules.calendar) {
ctx.store.modules.calendar.openTeam(id);
}
cb();
}));
};
var onReady = function(ctx, id, lm, roster, keys, cId, cb) {
var state = roster.getState();
var teamData = Util.find(ctx, [ "store", "proxy", "teams", id ]);
if (teamData) {
teamData.metadata = state.metadata;
}
delete ctx.nocache[id];
var team;
if (!ctx.store.proxy.teams[id]) {
return;
}
nThen((function(waitFor) {
onCacheReady(ctx, id, lm, roster, keys, cId, waitFor());
team = ctx.teams[id] || ctx.cache[id];
if (!keys.drive.edPrivate) {
return;
}
initRpc(ctx, team, keys.drive, waitFor((function() {})));
})).nThen((function(waitFor) {
team.userObject.fixFiles();
SF.checkMigration(team.secondaryKey, team.proxy?.drive, team.userObject, waitFor());
SF.loadSharedFolders(ctx.Store, ctx.store.network, team, team.proxy?.drive, team.userObject, waitFor, (function(data) {
ctx.progress += 70 / (ctx.numberOfTeams * data.max);
ctx.updateProgress({
progress: ctx.progress
});
}));
})).nThen((function() {
if (!team.rpc) {
return;
}
var list = getTeamChannelList(ctx, id);
var local = Hash.hashChannelList(list);
team.rpc.getServerHash((function(e, hash) {
if (e) {
return void console.warn(e);
}
if (hash !== local) {
team.rpc.reset(list, (function(e) {
if (e) {
console.warn(e);
}
}));
}
}));
})).nThen((function() {
team.offline = false;
if (ctx.onReadyHandlers[id]) {
ctx.onReadyHandlers[id].forEach((function(obj) {
if (typeof obj.cb === "function") {
obj.cb();
}
if (!obj.cId) {
return;
}
var idx = team.clients.indexOf(obj.cId);
if (idx === -1) {
team.clients.push(obj.cId);
}
}));
}
delete ctx.onReadyHandlers[id];
if (ctx.store.modules.calendar) {
ctx.store.modules.calendar.openTeam(id);
}
cb();
}));
};
var checkTeamChannels = function(ctx, id, channel, roster, waitFor, cb) {
var close = function() {
if (ctx.cache[id] || ctx.teams[id]) {
closeTeam(ctx, id);
}
delete ctx.store.proxy.teams[id];
delete ctx.onReadyHandlers[id];
waitFor.abort();
cb({
error: "ENOENT"
});
};
if (channel) {
ctx.store.anon_rpc.send("IS_NEW_CHANNEL", channel, waitFor((function(e, res) {
if (res && res.length && typeof res[0] === "object" && res[0].isNew) {
close();
}
})));
}
if (roster) {
ctx.store.anon_rpc.send("IS_NEW_CHANNEL", roster, waitFor((function(e, res) {
if (res && res.length && typeof res[0] === "object" && res[0].isNew) {
close();
}
})));
}
};
var openChannel = function(ctx, teamData, id, _cb, cache) {
var cb = Util.once(Util.mkAsync(_cb));
var hash = teamData.hash || teamData.roHash;
var secret = Hash.getSecrets("team", hash, teamData.password);
var crypto = Crypto.createEncryptor(secret.keys);
if (!teamData.roHash) {
teamData.roHash = Hash.getViewHashFromKeys(secret);
}
var keys = teamData.keys;
if (!keys.chat.validateKey && keys.chat.edit) {
var chatSecret = Hash.getSecrets("chat", keys.chat.edit);
keys.chat.validateKey = chatSecret.keys.validateKey;
}
var roster;
var lm;
var myKeys = {
curvePublic: ctx.store.proxy.curvePublic,
curvePrivate: ctx.store.proxy.curvePrivate
};
var rosterData = keys.roster || {};
var rosterKeys = rosterData.edit ? Crypto.Team.deriveMemberKeys(rosterData.edit, myKeys) : Crypto.Team.deriveGuestKeys(rosterData.view || "");
nThen((function(waitFor) {
if (cache) {
Cache.getChannelCache(secret.channel, waitFor((function(err, obj) {
var c = obj && obj.c;
if (!c) {
waitFor.abort();
cb({
error: "NOCACHE"
});
}
})));
Cache.getChannelCache(rosterKeys.channel, waitFor((function(err, obj) {
var c = obj && obj.c;
var k = obj && obj.k;
if (k && !rosterKeys.teamEdPublic) {
rosterKeys.teamEdPublic = k;
}
if (!c) {
waitFor.abort();
cb({
error: "NOCACHE"
});
}
})));
return;
}
ctx.Store.onReadyEvt.reg((() => {
checkTeamChannels(ctx, id, secret.channel, rosterKeys.channel, waitFor, cb);
}));
})).nThen((function(waitFor) {
var cacheRdy = {
lm: false,
roster: false,
check: function() {
if (!this.lm || !this.roster) {
return;
}
if (!cache) {
return;
}
ctx.progress += 30 / ctx.numberOfTeams;
ctx.updateProgress({
progress: ctx.progress
});
onCacheReady(ctx, id, lm, roster, keys, null, waitFor(cb));
this.check = function() {};
}
};
var cfg = {
data: {},
readOnly: !Boolean(secret.keys.signKey),
network: ctx.store.network || ctx.store.networkPromise,
channel: secret.channel,
crypto,
ChainPad,
Cache,
metadata: {
validateKey: secret.keys.validateKey || undefined
},
userName: "team",
classic: true
};
cfg.onMetadataUpdate = function() {
var team = ctx.teams[id];
if (!team) {
return;
}
ctx.emit("ROSTER_CHANGE", id, team.clients);
};
lm = Listmap.create(cfg);
lm.proxy.on("cacheready", (function() {
cacheRdy.lm = true;
cacheRdy.check();
}));
lm.proxy.on("ready", waitFor());
lm.proxy.on("error", (function(info) {
if (info && typeof info.loaded !== "undefined" && !info.loaded) {
cb({
error: "ECONNECT"
});
}
if (info && info.error) {
if (info.error === "EDELETED") {
closeTeam(ctx, id);
}
}
}));
Roster.create({
network: ctx.store.network || ctx.store.networkPromise,
channel: rosterKeys.channel,
keys: rosterKeys,
store: ctx.store,
lastKnownHash: rosterData.lastKnownHash,
onCacheReady: function(_roster) {
if (!cache) {
return;
}
if (_roster && _roster.error === "CORRUPTED") {
console.error("Corrupted roster cache, cant load this team offline", teamData);
if (lm && typeof lm.stop === "function") {
lm.stop();
}
waitFor.abort();
cb({
error: "CACHE_CORRUPTED_ROSTER"
});
return;
}
roster = _roster;
cacheRdy.roster = true;
cacheRdy.check();
},
Cache
}, waitFor((function(err, _roster) {
if (err) {
waitFor.abort();
console.error(err);
return void cb({
error: "ROSTER_ERROR"
});
}
roster = _roster;
rosterData.lastKnownHash = roster.getLastCheckpointHash();
var state = roster.getState();
var me = Util.find(ctx, [ "store", "proxy", "curvePublic" ]);
if (!state.members[me]) {
return;
}
onStoreReady.reg((function() {
if (!rosterData.edit) {
return;
}
var data = {};
var myData = Messaging.createData(ctx.store.proxy, false);
myData.pending = false;
data[ctx.store.proxy.curvePublic] = myData;
roster.describe(data, (function(err) {
if (!err) {
return;
}
if (err === "NO_CHANGE") {
return;
}
console.error(err);
}));
}));
})));
})).nThen((function(waitFor) {
var state = roster.getState();
var me = Util.find(ctx, [ "store", "proxy", "curvePublic" ]);
if (!state.members || !Object.keys(state.members).length) {
lm.stop();
roster.stop();
lm.proxy = {};
cb({
error: "EINVAL"
});
waitFor.abort();
console.error(JSON.stringify(state));
Feedback.send("ROSTER_CORRUPTED");
return;
}
if (!state.members[me]) {
lm.stop();
roster.stop();
lm.proxy = {};
delete ctx.store.proxy.teams[id];
ctx.updateMetadata();
cb({
error: "EFORBIDDEN"
});
waitFor.abort();
return;
}
var s = state.members[me];
var teamEdPrivate = Util.find(teamData, [ "keys", "drive", "edPrivate" ]);
if ((!teamData.hash || !teamEdPrivate) && [ "ADMIN", "MEMBER" ].indexOf(s.role) !== -1) {
console.warn("Missing edit rights: demote to viewer");
var data = {};
data[ctx.store.proxy.curvePublic] = {
role: "VIEWER"
};
roster.describe(data, (function(err) {
Feedback.send("TEAM_RIGHTS_FIXED");
delete teamData.hash;
delete teamData.keys.drive.edPrivate;
delete teamData.keys.chat.edit;
if (!err) {
return;
}
if (err === "NO_CHANGE") {
return;
}
console.error(err);
}));
} else if ((!teamData.hash || !teamEdPrivate) && s.role === "OWNER") {
Feedback.send("TEAM_RIGHTS_OWNER");
}
})).nThen((function() {
if (!cache) {
ctx.progress += 30 / ctx.numberOfTeams;
ctx.updateProgress({
progress: ctx.progress
});
}
onReady(ctx, id, lm, roster, keys, null, cb);
}));
};
var createTeam = function(ctx, data, cId, _cb) {
var cb = Util.once(_cb);
var password = Hash.createChannelId();
var hash = Hash.createRandomHash("team", password);
var secret = Hash.getSecrets("team", hash, password);
var roHash = Hash.getViewHashFromKeys(secret);
var keyPair = Nacl.sign.keyPair();
var curvePair = Nacl.box.keyPair();
var rosterSeed = Crypto.Team.createSeed();
var rosterKeys = Crypto.Team.deriveMemberKeys(rosterSeed, {
curvePublic: ctx.store.proxy.curvePublic,
curvePrivate: ctx.store.proxy.curvePrivate
});
var roster;
var chatSecret = Hash.getSecrets("chat");
var chatHashes = Hash.getHashes(chatSecret);
var config = {
network: ctx.store.network,
channel: secret.channel,
data: {},
validateKey: secret.keys.validateKey,
crypto: Crypto.createEncryptor(secret.keys),
logLevel: 1,
classic: true,
ChainPad,
Cache,
owners: [ ctx.store.proxy.edPublic ]
};
nThen((function(waitFor) {
Roster.create({
network: ctx.store.network || ctx.store.networkPromise,
channel: rosterKeys.channel,
owners: [ ctx.store.proxy.edPublic ],
keys: rosterKeys,
store: ctx.store,
lastKnownHash: void 0,
newTeam: true,
Cache
}, waitFor((function(err, _roster) {
if (err) {
waitFor.abort();
console.error(err);
return void cb({
error: "ROSTER_ERROR"
});
}
roster = _roster;
var myData = Messaging.createData(ctx.store.proxy);
delete myData.channel;
roster.init(myData, waitFor((function(err) {
if (err) {
waitFor.abort();
return void cb({
error: "ROSTER_INIT_ERROR"
});
}
})));
})));
var crypto = Crypto.createEncryptor(chatSecret.keys);
var chatCfg = {
network: ctx.store.network,
channel: chatSecret.channel,
noChainPad: true,
crypto,
metadata: {
validateKey: chatSecret.keys.validateKey,
owners: [ ctx.store.proxy.edPublic ]
}
};
var chatReady = waitFor();
var cpNf2;
chatCfg.onReady = function() {
if (cpNf2) {
cpNf2.stop();
}
chatReady();
};
chatCfg.onError = function() {
waitFor.abort();
return void cb({
error: "CHAT_INIT_ERROR"
});
};
cpNf2 = CpNetflux.start(chatCfg);
})).nThen((function(waitFor) {
roster.metadata({
name: data.name
}, waitFor((function(err) {
if (err) {
waitFor.abort();
return void cb({
error: "ROSTER_INIT_ERROR"
});
}
})));
})).nThen((function() {
var id = Util.createRandomInteger();
config.onMetadataUpdate = function() {
var team = ctx.teams[id];
if (!team) {
return;
}
ctx.emit("ROSTER_CHANGE", id, team.clients);
};
var lm = Listmap.create(config);
var proxy = lm.proxy;
proxy.version = 2;
proxy.on("ready", (function() {
var keys = {
mailbox: {
channel: Hash.createChannelId(),
viewed: [],
keys: {
curvePrivate: Nacl.util.encodeBase64(curvePair.secretKey),
curvePublic: Nacl.util.encodeBase64(curvePair.publicKey)
}
},
drive: {
edPrivate: Nacl.util.encodeBase64(keyPair.secretKey),
edPublic: Nacl.util.encodeBase64(keyPair.publicKey)
},
chat: {
edit: chatHashes.editHash,
view: chatHashes.viewHash,
validateKey: chatSecret.keys.validateKey,
channel: chatSecret.channel
},
roster: {
channel: rosterKeys.channel,
edit: rosterSeed,
view: rosterKeys.viewKeyStr
}
};
var t = ctx.store.proxy.teams[id] = {
owner: true,
channel: secret.channel,
hash,
roHash,
password,
keys,
metadata: {
name: data.name
}
};
proxy.drive = {};
onReady(ctx, id, lm, roster, keys, cId, (function() {
Feedback.send("TEAM_CREATION");
ctx.store.mailbox.open("team-" + id, t.keys.mailbox, (function() {}), true, {
owners: t.keys.drive.edPublic
});
ctx.updateMetadata();
cb();
}));
})).on("error", (function(info) {
if (info && typeof info.loaded !== "undefined" && !info.loaded) {
cb({
error: "ECONNECT"
});
}
if (info && info.error) {
if (info.error === "EDELETED") {
closeTeam(ctx, id);
}
}
}));
}));
};
var deleteTeam = function(ctx, data, cId, cb) {
var teamId = data.teamId;
if (!teamId) {
return void cb({
error: "EINVAL"
});
}
var team = ctx.teams[teamId];
var teamData = Util.find(ctx, [ "store", "proxy", "teams", teamId ]);
if (!team || !teamData) {
return void cb({
error: "ENOENT"
});
}
var state = team.roster.getState();
var curvePublic = Util.find(ctx, [ "store", "proxy", "curvePublic" ]);
var me = state.members[curvePublic];
if (!me || me.role !== "OWNER") {
return cb({
error: "EFORBIDDEN"
});
}
var edPublic = Util.find(ctx, [ "store", "proxy", "edPublic" ]);
var teamEdPublic = Util.find(teamData, [ "keys", "drive", "edPublic" ]);
nThen((function(waitFor) {
ctx.Store.anonRpcMsg(null, {
msg: "GET_METADATA",
data: teamData.channel
}, waitFor((function(obj) {
if (obj && obj.error) {
waitFor.abort();
return cb({
error: obj.error
});
}
var metadata = obj[0];
if (metadata && Array.isArray(metadata.owners) && metadata.owners.indexOf(edPublic) !== -1) {
return;
}
waitFor.abort();
cb({
error: "EFORBIDDEN"
});
})));
})).nThen((function(waitFor) {
team.proxy.delete = true;
var ownedPads = team.manager.getChannelsList("owned");
var sem = Util.Saferphore.create(10);
ownedPads.forEach((function(c) {
var w = waitFor();
sem.take((function(give) {
var otherOwners = false;
nThen((function(_w) {
if (c.length !== 32) {
return;
}
ctx.Store.anonRpcMsg(null, {
msg: "GET_METADATA",
data: c
}, _w((function(obj) {
if (obj && obj.error) {
give();
return void _w.abort();
}
var md = obj[0];
var isOwner = md && Array.isArray(md.owners) && md.owners.indexOf(teamEdPublic) !== -1;
if (!isOwner) {
give();
return void _w.abort();
}
otherOwners = md.owners.some((function(ed) {
return ed !== teamEdPublic;
}));
})));
})).nThen((function(_w) {
if (otherOwners) {
ctx.Store.setPadMetadata(null, {
channel: c,
command: "RM_OWNERS",
value: [ teamEdPublic ]
}, _w());
return;
}
team.rpc.removeOwnedChannel(c, _w((function(err) {
if (err) {
console.error(err);
}
})));
})).nThen((function() {
give();
w();
}));
}));
}));
})).nThen((function(waitFor) {
team.rpc.removePins(waitFor((function(err) {
if (err) {
console.error(err);
}
})));
var mailboxChan = Util.find(teamData, [ "keys", "mailbox", "channel" ]);
team.rpc.removeOwnedChannel(mailboxChan, waitFor((function(err) {
if (err) {
console.error(err);
}
})));
var rosterChan = Util.find(teamData, [ "keys", "roster", "channel" ]);
ctx.store.rpc.removeOwnedChannel(rosterChan, waitFor((function(err) {
if (err) {
console.error(err);
}
})));
var chatChan = Util.find(teamData, [ "keys", "chat", "channel" ]);
ctx.store.rpc.removeOwnedChannel(chatChan, waitFor((function(err) {
if (err) {
console.error(err);
}
})));
ctx.store.rpc.removeOwnedChannel(teamData.channel, waitFor((function(err) {
if (err) {
console.error(err);
}
})));
})).nThen((function() {
Feedback.send("TEAM_DELETION");
closeTeam(ctx, teamId);
cb();
}));
};
var joinTeam = function(ctx, data, cId, cb) {
var team = data.team;
if (!(team.hash || team.roHash) || !team.channel || !team.password || !team.keys || !team.metadata) {
return void cb({
error: "EINVAL"
});
}
let myTeams = ctx.store.proxy.teams;
if (Object.values(myTeams).some((obj => obj.channel === team.channel))) {
return void cb({
error: "EEXISTS"
});
}
var id = Util.createRandomInteger();
ctx.store.proxy.teams[id] = team;
ctx.onReadyHandlers[id] = [];
openChannel(ctx, team, id, (function(obj) {
if (!(obj && obj.error)) {
console.debug("Team joined:" + id);
}
var t = ctx.store.proxy.teams[id];
ctx.store.mailbox.open("team-" + id, t.keys.mailbox, (function() {}), true, {
owners: t.keys.drive.edPublic
});
ctx.updateMetadata();
cb(obj);
}));
};
var leaveTeam = function(ctx, data, cId, cb) {
var teamId = data.teamId;
if (!teamId) {
return void cb({
error: "EINVAL"
});
}
var team = ctx.teams[teamId];
if (!team) {
return void cb({
error: "ENOENT"
});
}
if (!team.roster) {
return void cb({
error: "NO_ROSTER"
});
}
var curvePublic = ctx.store.proxy.curvePublic;
team.roster.remove([ curvePublic ], (function(err) {
if (err) {
return void cb({
error: err
});
}
closeTeam(ctx, teamId);
cb();
}));
};
var getTeamRoster = function(ctx, data, cId, cb) {
var teamId = data.teamId;
if (!teamId) {
return void cb({
error: "EINVAL"
});
}
var teamData = Util.find(ctx, [ "store", "proxy", "teams", teamId ]);
if (!teamData) {
return void cb({
error: "ENOENT"
});
}
var team = ctx.teams[teamId];
if (!team) {
return void cb({
error: "ENOENT"
});
}
if (!team.roster) {
return void cb({
error: "NO_ROSTER"
});
}
var state = team.roster.getState() || {};
var members = state.members || {};
var md;
nThen((function(waitFor) {
ctx.Store.getPadMetadata(null, {
channel: teamData.channel
}, waitFor((function(obj) {
if (obj && obj.error) {
md = team.listmap.metadata || {};
return;
}
md = obj;
})));
})).nThen((function() {
ctx.pending_owners = md.pending_owners;
if (Array.isArray(md.pending_owners)) {
md.pending_owners.forEach((function(ed) {
var member;
Object.keys(members).some((function(curve) {
if (members[curve].edPublic === ed) {
member = members[curve];
return true;
}
}));
if (!member && teamData.owner) {
var removeOwnership = function(chan) {
ctx.Store.setPadMetadata(null, {
channel: chan,
command: "RM_PENDING_OWNERS",
value: [ ed ]
}, (function() {}));
};
removeOwnership(teamData.channel);
removeOwnership(Util.find(teamData, [ "keys", "roster", "channel" ]));
removeOwnership(Util.find(teamData, [ "keys", "chat", "channel" ]));
return;
}
member.pendingOwner = true;
}));
}
if (ctx.store.messenger) {
var chatData = team.getChatData();
var online = ctx.store.messenger.getOnlineList(chatData.channel) || [];
online.forEach((function(curve) {
if (members[curve]) {
members[curve].online = true;
}
}));
}
Object.keys(members).forEach((function(curve) {
var member = members[curve];
if (!member.inviteChannel) {
return;
}
if (!member.hash) {
return;
}
if (!teamData.hash) {
delete member.hash;
return;
}
try {
member.hash = Invite.decryptHash(member.hash, teamData.hash);
} catch (e) {
console.error(e);
}
}));
cb(members);
}));
};
var getEditableFolders = function(ctx, data, cId, cb) {
var teamId = data.teamId;
if (!teamId) {
return void cb({
error: "EINVAL"
});
}
var team = ctx.teams[teamId];
if (!team) {
return void cb({
error: "ENOENT"
});
}
var folders = team.manager.folders || {};
var ids = Object.keys(folders).filter((function(id) {
return !folders[id].proxy.version;
}));
cb(ids.map((function(id) {
var uo = Util.find(team, [ "user", "userObject" ]);
return {
name: Util.find(folders, [ id, "proxy", "metadata", "title" ]),
path: uo ? uo.findFile(id)[0] : []
};
})));
};
var getTeamMetadata = function(ctx, data, cId, cb) {
var teamId = data.teamId;
if (!teamId) {
return void cb({
error: "EINVAL"
});
}
var team = ctx.teams[teamId];
if (!team) {
return void cb({
error: "ENOENT"
});
}
if (!team.roster) {
return void cb({
error: "NO_ROSTER"
});
}
var state = team.roster.getState() || {};
var md = state.metadata || {};
md.offline = team.offline;
cb(md);
};
var setTeamMetadata = function(ctx, data, cId, cb) {
var teamId = data.teamId;
if (!teamId) {
return void cb({
error: "EINVAL"
});
}
var team = ctx.teams[teamId];
if (!team) {
return void cb({
error: "ENOENT"
});
}
if (team.offline) {
return void cb({
error: "OFFLINE"
});
}
if (!team.roster) {
return void cb({
error: "NO_ROSTER"
});
}
if (data.metadata) {
delete data.metadata.offline;
}
team.roster.metadata(data.metadata, (function(err) {
if (err) {
return void cb({
error: err
});
}
var localTeam = ctx.store.proxy.teams[teamId];
if (localTeam) {
localTeam.metadata = data.metadata;
}
cb();
}));
};
var offerOwnership = function(ctx, data, cId, _cb) {
var cb = Util.once(_cb);
var teamId = data.teamId;
if (!teamId) {
return void cb({
error: "EINVAL"
});
}
var teamData = Util.find(ctx, [ "store", "proxy", "teams", teamId ]);
if (!teamData) {
return void cb({
error: "ENOENT"
});
}
var team = ctx.teams[teamId];
if (!team) {
return void cb({
error: "ENOENT"
});
}
if (!team.roster) {
return void cb({
error: "NO_ROSTER"
});
}
if (!data.curvePublic) {
return void cb({
error: "MISSING_DATA"
});
}
var state = team.roster.getState();
var user = state.members[data.curvePublic];
nThen((function(waitFor) {
var onError = function(res) {
var err = res && res.error;
if (err) {
console.error(err);
waitFor.abort();
return void cb({
error: err
});
}
};
var addPendingOwner = function(chan) {
ctx.Store.setPadMetadata(null, {
channel: chan,
command: "ADD_PENDING_OWNERS",
value: [ user.edPublic ]
}, waitFor(onError));
};
addPendingOwner(teamData.channel);
addPendingOwner(Util.find(teamData, [ "keys", "roster", "channel" ]));
addPendingOwner(Util.find(teamData, [ "keys", "chat", "channel" ]));
})).nThen((function(waitFor) {
var obj = {};
obj[user.curvePublic] = {
role: "OWNER"
};
team.roster.describe(obj, waitFor((function(err) {
if (err) {
console.error(err);
}
})));
})).nThen((function(waitFor) {
ctx.store.mailbox.sendTo("ADD_OWNER", {
teamChannel: teamData.channel,
chatChannel: Util.find(teamData, [ "keys", "chat", "channel" ]),
rosterChannel: Util.find(teamData, [ "keys", "roster", "channel" ]),
title: teamData.metadata.name
}, {
channel: user.notifications,
curvePublic: user.curvePublic
}, waitFor());
})).nThen((function() {
cb();
}));
};
var revokeOwnership = function(ctx, teamId, user, _cb) {
var cb = Util.once(_cb);
if (!teamId) {
return void cb({
error: "EINVAL"
});
}
var teamData = Util.find(ctx, [ "store", "proxy", "teams", teamId ]);
if (!teamData) {
return void cb({
error: "ENOENT"
});
}
var team = ctx.teams[teamId];
if (!team) {
return void cb({
error: "ENOENT"
});
}
var isPendingOwner = user.pendingOwner;
nThen((function(waitFor) {
var cmd = isPendingOwner ? "RM_PENDING_OWNERS" : "RM_OWNERS";
var onError = function(res) {
var err = res && res.error;
if (err) {
console.error(err);
waitFor.abort();
return void cb(err);
}
};
var removeOwnership = function(chan) {
ctx.Store.setPadMetadata(null, {
channel: chan,
command: cmd,
value: [ user.edPublic ]
}, waitFor(onError));
};
removeOwnership(teamData.channel);
removeOwnership(Util.find(teamData, [ "keys", "roster", "channel" ]));
removeOwnership(Util.find(teamData, [ "keys", "chat", "channel" ]));
})).nThen((function(waitFor) {
var obj = {};
obj[user.curvePublic] = {
role: "ADMIN",
pendingOwner: false
};
team.roster.describe(obj, waitFor((function(err) {
if (err) {
console.error(err);
}
})));
})).nThen((function(waitFor) {
ctx.store.mailbox.sendTo("RM_OWNER", {
teamChannel: teamData.channel,
title: teamData.metadata.name,
pending: isPendingOwner
}, {
channel: user.notifications,
curvePublic: user.curvePublic
}, waitFor());
})).nThen((function() {
cb();
}));
};
var answerOwnership = function(ctx, data, cId, cb) {
var myTeams = ctx.store.proxy.teams;
var teamId;
Object.keys(myTeams).forEach((function(id) {
if (myTeams[id].channel === data.teamChannel) {
teamId = id;
return true;
}
}));
if (!teamId) {
return void cb({
error: "EINVAL"
});
}
var teamData = Util.find(ctx, [ "store", "proxy", "teams", teamId ]);
if (!teamData) {
return void cb({
error: "ENOENT"
});
}
var team = ctx.teams[teamId];
if (!team) {
return void cb({
error: "ENOENT"
});
}
if (!team.roster) {
return void cb({
error: "NO_ROSTER"
});
}
var obj = {};
if (data.answer) {
teamData.owner = true;
return;
}
obj[ctx.store.proxy.curvePublic] = {
role: "ADMIN"
};
team.roster.describe(obj, (function(err) {
if (err) {
return void cb({
error: err
});
}
cb();
}));
};
var getInviteData = function(ctx, teamId, edit) {
var teamData = Util.find(ctx, [ "store", "proxy", "teams", teamId ]);
if (!teamData) {
return {};
}
var data = Util.clone(teamData);
if (!edit) {
delete data.hash;
delete data.keys.drive.edPrivate;
delete data.keys.chat.edit;
}
delete data.owner;
return data;
};
var updateMyRights = function(ctx, teamId, hash) {
if (!teamId) {
return true;
}
var teamData = Util.find(ctx, [ "store", "proxy", "teams", teamId ]);
if (!teamData) {
return true;
}
var team = ctx.teams[teamId];
if (!team) {
return true;
}
var secret = Hash.getSecrets("team", hash || teamData.roHash, teamData.password);
SF.upgrade(teamData.channel, secret);
if (team.userObject) {
team.userObject.setReadOnly(!secret.keys.secondaryKey, secret.keys.secondaryKey);
}
if (secret.keys.secondaryKey) {
try {
ctx.store.modules.calendar.upgradeTeam(teamId);
} catch (e) {
console.error(e);
}
}
if (!secret.keys.secondaryKey && team.rpc) {
team.rpc.destroy();
}
var folders = Util.find(team, [ "proxy", "drive", "sharedFolders" ]);
Object.keys(folders || {}).forEach((function(sfId) {
var data = team.manager.getSharedFolderData(sfId);
var parsed = Hash.parsePadUrl(data.href || data.roHref);
var secret = Hash.getSecrets(parsed.type, parsed.hash, data.password);
SF.upgrade(secret.channel, secret);
var uo = Util.find(team, [ "manager", "folders", sfId, "userObject" ]);
if (uo) {
uo.setReadOnly(!secret.keys.secondaryKey, secret.keys.secondaryKey);
}
}));
ctx.updateMetadata();
ctx.emit("ROSTER_CHANGE_RIGHTS", teamId, team.clients);
};
var changeMyRights = function(ctx, teamId, state, data, cb) {
if (!teamId) {
return void cb(false);
}
var teamData = Util.find(ctx, [ "store", "proxy", "teams", teamId ]);
if (!teamData) {
return void cb(false);
}
var onReady = ctx.onReadyHandlers[teamId];
var team = ctx.teams[teamId];
if (teamData.channel !== data.channel || teamData.password !== data.password) {
return void cb(false);
}
if (state) {
teamData.hash = data.hash;
teamData.keys.drive.edPrivate = data.keys.drive.edPrivate;
teamData.keys.chat.edit = data.keys.chat.edit;
} else {
delete teamData.hash;
delete teamData.keys.drive.edPrivate;
delete teamData.keys.chat.edit;
}
if (!team && Array.isArray(onReady)) {
onReady.push({
cb: function() {
changeMyRights(ctx, teamId, state, data, cb);
}
});
return;
}
if (!team) {
return void cb(false);
}
if (state) {
initRpc(ctx, team, teamData.keys.drive, (function() {
team.manager.addPin(team.pin, team.unpin);
}));
var secret = Hash.getSecrets("team", data.hash, teamData.password);
team.secondaryKey = secret && secret.keys.secondaryKey;
var crypto = Crypto.createEncryptor(secret.keys);
team.listmap.setReadOnly(false, crypto);
} else {
delete team.secondaryKey;
if (team.rpc && team.rpc.destroy) {
team.rpc.destroy();
}
team.manager.removePin();
team.listmap.setReadOnly(true);
}
updateMyRights(ctx, teamId, data.hash);
cb(true);
};
var changeEditRights = function(ctx, teamId, user, state, cb) {
if (!teamId) {
return void cb({
error: "EINVAL"
});
}
var teamData = Util.find(ctx, [ "store", "proxy", "teams", teamId ]);
if (!teamData) {
return void cb({
error: "ENOENT"
});
}
var team = ctx.teams[teamId];
if (!team) {
return void cb({
error: "ENOENT"
});
}
ctx.store.mailbox.sendTo("TEAM_EDIT_RIGHTS", {
state,
teamData: getInviteData(ctx, teamId, state)
}, {
channel: user.notifications,
curvePublic: user.curvePublic
}, cb);
};
var describeUser = function(ctx, data, cId, cb) {
var teamId = data.teamId;
if (!teamId) {
return void cb({
error: "EINVAL"
});
}
var teamData = Util.find(ctx, [ "store", "proxy", "teams", teamId ]);
var team = ctx.teams[teamId];
if (!teamData || !team) {
return void cb({
error: "ENOENT"
});
}
if (!team.roster) {
return void cb({
error: "NO_ROSTER"
});
}
if (!data.curvePublic || !data.data) {
return void cb({
error: "MISSING_DATA"
});
}
var state = team.roster.getState();
var user = state.members[data.curvePublic];
var md;
nThen((function(waitFor) {
ctx.Store.getPadMetadata(null, {
channel: teamData.channel
}, waitFor((function(obj) {
if (obj && obj.error) {
md = team.listmap.metadata || {};
return;
}
md = obj;
})));
})).nThen((function() {
user.pendingOwner = Array.isArray(md.pending_owners) && md.pending_owners.indexOf(user.edPublic) !== -1;
if (user.role === "OWNER" && data.data.role !== "OWNER") {
revokeOwnership(ctx, teamId, user, (function(err) {
if (!err) {
return void cb();
}
console.error(err);
return void cb({
error: err
});
}));
return;
}
if (user.role === "VIEWER" && data.data.role !== "VIEWER") {
changeEditRights(ctx, teamId, user, true, (function(obj) {
return void cb(obj);
}));
}
if (user.role !== "VIEWER" && data.data.role === "VIEWER") {
changeEditRights(ctx, teamId, user, false, (function(obj) {
return void cb(obj);
}));
}
var obj = {};
obj[data.curvePublic] = data.data;
team.roster.describe(obj, (function(err) {
if (err) {
return void cb({
error: err
});
}
cb();
}));
}));
};
var inviteToTeam = function(ctx, data, cId, cb) {
var teamId = data.teamId;
if (!teamId) {
return void cb({
error: "EINVAL"
});
}
var team = ctx.teams[teamId];
if (!team) {
return void cb({
error: "ENOENT"
});
}
if (!team.roster) {
return void cb({
error: "NO_ROSTER"
});
}
var user = data.user;
if (!user || !user.curvePublic || !user.notifications) {
return void cb({
error: "MISSING_DATA"
});
}
delete user.channel;
delete user.lastKnownHash;
user.pending = true;
var obj = {};
obj[user.curvePublic] = user;
obj[user.curvePublic].role = "VIEWER";
team.roster.add(obj, (function(err) {
if (err && err !== "NO_CHANGE") {
return void cb({
error: err
});
}
ctx.store.mailbox.sendTo("INVITE_TO_TEAM", {
team: getInviteData(ctx, teamId)
}, {
channel: user.notifications,
curvePublic: user.curvePublic
}, (function(obj) {
cb(obj);
}));
}));
};
var removeUser = function(ctx, data, cId, cb) {
var teamId = data.teamId;
if (!teamId) {
return void cb({
error: "EINVAL"
});
}
var team = ctx.teams[teamId];
if (!team) {
return void cb({
error: "ENOENT"
});
}
if (!team.roster) {
return void cb({
error: "NO_ROSTER"
});
}
if (!data.curvePublic) {
return void cb({
error: "MISSING_DATA"
});
}
var state = team.roster.getState();
var userData = state.members[data.curvePublic];
team.roster.remove([ data.curvePublic ], (function(err) {
if (err) {
return void cb({
error: err
});
}
if (!userData || !userData.notifications) {
return cb();
}
ctx.store.mailbox.sendTo("KICKED_FROM_TEAM", {
pending: data.pending,
teamChannel: getInviteData(ctx, teamId).channel,
teamName: getInviteData(ctx, teamId).metadata.name
}, {
channel: userData.notifications,
curvePublic: userData.curvePublic
}, (function(obj) {
cb(obj);
}));
}));
};
var removeClient = function(ctx, cId) {
Object.keys(ctx.onReadyHandlers).forEach((function(teamId) {
var idx = -1;
ctx.onReadyHandlers[teamId].some((function(obj, _idx) {
if (obj.cId === cId) {
idx = _idx;
return true;
}
}));
if (idx !== -1) {
ctx.onReadyHandlers[teamId].splice(idx, 1);
}
}));
Object.keys(ctx.teams).forEach((function(id) {
var clients = ctx.teams[id].clients;
var idx = clients.indexOf(cId);
if (idx !== -1) {
clients.splice(idx, 1);
}
}));
};
var subscribe = function(ctx, id, cId, cb) {
removeClient(ctx, cId);
try {
ctx.store.messenger.removeClient(cId);
} catch (e) {}
openCachedTeamChat = function() {};
if (!id) {
return void cb();
}
if (ctx.onReadyHandlers[id] && !ctx.teams[id]) {
var _idx = ctx.onReadyHandlers[id].indexOf(cId);
if (_idx === -1) {
ctx.onReadyHandlers[id].push({
cId,
cb
});
}
return;
}
if (!ctx.teams[id]) {
return void cb({
error: "EINVAL"
});
}
var clients = ctx.teams[id].clients;
var idx = clients.indexOf(cId);
if (idx === -1) {
clients.push(cId);
}
cb();
};
var openTeamChat = function(ctx, data, cId, cb) {
var team = ctx.teams[data.teamId];
if (!team) {
return void cb({
error: "ENOENT"
});
}
var onUpdate = function() {
ctx.emit("ROSTER_CHANGE", data.teamId, team.clients);
};
if (ctx.store.messenger) {
ctx.store.messenger.openTeamChat(team.getChatData(), onUpdate, cId, cb);
} else {
openCachedTeamChat = function() {
ctx.store.messenger.openTeamChat(team.getChatData(), onUpdate, cId, cb);
};
}
};
var createInviteLink = function(ctx, data, cId, _cb) {
var cb = Util.mkAsync(Util.once(_cb));
var teamId = data.teamId;
var team = ctx.teams[data.teamId];
var seeds = data.seeds;
var bytes64 = data.bytes64;
if (!teamId || !team) {
return void cb({
error: "EINVAL"
});
}
var roster = team.roster;
var teamName;
try {
teamName = roster.getState().metadata.name;
} catch (err) {
return void cb({
error: "TEAM_NAME_ERR"
});
}
var message = data.message;
var name = data.name;
var hash = data.hash;
var teamData = Util.find(ctx, [ "store", "proxy", "teams", teamId ]);
try {
var encryptedHash = Invite.encryptHash(hash, teamData.hash);
} catch (e) {
console.error(e);
}
var previewKeys = Invite.derivePreviewKeys(seeds.preview);
var inviteKeys = Invite.deriveInviteKeys(bytes64);
var ephemeralKeys = Invite.generateKeys();
var role = data.role || "VIEWER";
var uses = data.uses || 1;
nThen((function(w) {
(function() {
var sign = Invite.generateSignPair();
var putOpts = {
initialState: "{}",
network: ctx.store.network,
metadata: {
owners: [ ctx.store.proxy.edPublic, ephemeralKeys.edPublic ]
}
};
putOpts.metadata.validateKey = sign.validateKey;
var previewContent = {
teamName,
message,
author: Messaging.createData(ctx.store.proxy, false),
displayName: name
};
var cryptput_config = {
channel: previewKeys.channel,
type: "pad",
version: 2,
keys: {
cryptKey: previewKeys.cryptKey,
validateKey: sign.validateKey,
signKey: sign.signKey
}
};
Crypt.put(cryptput_config, JSON.stringify(previewContent), w((function(err) {
if (err) {
console.error("CRYPTPUT_ERR", err);
w.abort();
return void cb({
error: "SET_PREVIEW_CONTENT"
});
}
})), putOpts);
})();
(function() {
var sign = Invite.generateSignPair();
var putOpts = {
initialState: "{}",
network: ctx.store.network,
metadata: {
owners: [ ctx.store.proxy.edPublic, ephemeralKeys.edPublic ]
}
};
putOpts.metadata.validateKey = sign.validateKey;
var inviteContent = {
teamData: getInviteData(ctx, teamId, role === "MEMBER"),
ephemeral: {
edPublic: ephemeralKeys.edPublic,
edPrivate: ephemeralKeys.edPrivate,
curvePublic: ephemeralKeys.curvePublic,
curvePrivate: ephemeralKeys.curvePrivate
}
};
var cryptput_config = {
channel: inviteKeys.channel,
type: "pad",
version: 2,
keys: {
cryptKey: inviteKeys.cryptKey,
validateKey: sign.validateKey,
signKey: sign.signKey
}
};
Crypt.put(cryptput_config, JSON.stringify(inviteContent), w((function(err) {
if (err) {
console.error("CRYPTPUT_ERR", err);
w.abort();
return void cb({
error: "SET_PREVIEW_CONTENT"
});
}
})), putOpts);
})();
})).nThen((function(w) {
team.pin([ inviteKeys.channel, previewKeys.channel ], (function(obj) {
if (obj && obj.error) {
console.error(obj.error);
}
}));
Invite.createRosterEntry(team.roster, {
curvePublic: ephemeralKeys.curvePublic,
content: {
curvePublic: ephemeralKeys.curvePublic,
displayName: data.name,
pending: true,
remaining: uses,
totalUses: uses,
role,
hash: encryptedHash,
inviteChannel: inviteKeys.channel,
previewChannel: previewKeys.channel
}
}, w((function(err) {
if (err) {
w.abort();
cb(err);
}
})));
})).nThen((function() {
cb();
}));
};
var getPreviewContent = function(ctx, data, cId, cb) {
var seeds = data.seeds;
var previewKeys;
try {
previewKeys = Invite.derivePreviewKeys(seeds.preview);
} catch (err) {
return void cb({
error: "INVALID_SEEDS"
});
}
Crypt.get({
channel: previewKeys.channel,
type: "pad",
version: 2,
keys: {
cryptKey: previewKeys.cryptKey
}
}, (function(err, val) {
if (err) {
return void cb({
error: err
});
}
if (!val) {
return void cb({
error: "DELETED"
});
}
var json = Util.tryParse(val);
if (!json) {
return void cb({
error: "parseError"
});
}
cb(json);
}), {
network: ctx.store.network,
initialState: "{}"
});
};
var getInviteContent = function(ctx, data, cId, cb) {
var bytes64 = data.bytes64;
var previewKeys;
try {
previewKeys = Invite.deriveInviteKeys(bytes64);
} catch (err) {
return void cb({
error: "INVALID_SEEDS"
});
}
Crypt.get({
channel: previewKeys.channel,
type: "pad",
version: 2,
keys: {
cryptKey: previewKeys.cryptKey
}
}, (function(err, val) {
if (err) {
return void cb({
error: err
});
}
if (!val) {
return void cb({
error: "DELETED"
});
}
var json = Util.tryParse(val);
if (!json) {
return void cb({
error: "parseError"
});
}
cb(json);
}), {
network: ctx.store.network,
initialState: "{}"
});
};
var acceptLinkInvitation = function(ctx, data, cId, cb) {
var inviteContent;
var rosterState;
nThen((function(waitFor) {
getInviteContent(ctx, data, cId, waitFor((function(obj) {
if (obj && obj.error) {
waitFor.abort();
return void cb(obj);
}
inviteContent = obj;
})));
})).nThen((function(waitFor) {
var chan = Util.find(inviteContent, [ "teamData", "channel" ]);
var myTeams = ctx.store.proxy.teams || {};
var isMember = Object.keys(myTeams).some((function(k) {
var t = myTeams[k];
return t.channel === chan;
}));
if (isMember) {
waitFor.abort();
return void cb({
error: "ALREADY_MEMBER"
});
}
var rosterData = Util.find(inviteContent, [ "teamData", "keys", "roster" ]);
var myKeys = inviteContent.ephemeral;
if (!rosterData || !myKeys) {
waitFor.abort();
return void cb({
error: "INVALID_INVITE_CONTENT"
});
}
var rosterKeys = Crypto.Team.deriveMemberKeys(rosterData.edit, myKeys);
Roster.create({
network: ctx.store.network || ctx.store.networkPromise,
channel: rosterData.channel,
keys: rosterKeys,
store: ctx.store,
Cache
}, waitFor((function(err, roster) {
if (err) {
waitFor.abort();
console.error(err);
return void cb({
error: "ROSTER_ERROR"
});
}
var myData = Messaging.createData(ctx.store.proxy, false);
var state = roster.getState();
rosterState = state.members[myKeys.curvePublic];
roster.accept(myData.curvePublic, waitFor((function(err) {
roster.stop();
if (err) {
waitFor.abort();
console.error(err);
return void cb({
error: "ACCEPT_ERROR"
});
}
})));
})));
})).nThen((function() {
var tempRpc = {};
if (!rosterState.remaining || rosterState.remaining === 1) {
initRpc(ctx, tempRpc, inviteContent.ephemeral, (function(err) {
if (err) {
return;
}
var rpc = tempRpc.rpc;
if (rosterState.inviteChannel) {
rpc.removeOwnedChannel(rosterState.inviteChannel, (function(err) {
if (err) {
console.error(err);
}
}));
}
if (rosterState.previewChannel) {
rpc.removeOwnedChannel(rosterState.previewChannel, (function(err) {
if (err) {
console.error(err);
}
}));
}
}));
}
joinTeam(ctx, {
team: inviteContent.teamData
}, cId, cb);
}));
};
var deriveMailbox = function(team) {
if (!team) {
return;
}
if (team.keys && team.keys.mailbox) {
return team.keys.mailbox;
}
var strSeed = Util.find(team, [ "keys", "roster", "edit" ]);
if (!strSeed) {
return;
}
var hash = Nacl.hash(Nacl.util.decodeUTF8(strSeed));
var seed = hash.slice(0, 32);
var mailboxChannel = Util.uint8ArrayToHex(hash.slice(32, 48));
var curvePair = Nacl.box.keyPair.fromSecretKey(seed);
return {
channel: mailboxChannel,
viewed: [],
keys: {
curvePrivate: Nacl.util.encodeBase64(curvePair.secretKey),
curvePublic: Nacl.util.encodeBase64(curvePair.publicKey)
}
};
};
Team.init = function(cfg, waitFor, emit) {
var team = {};
var store = cfg.store;
if (!store.loggedIn || !store.proxy.edPublic) {
return;
}
if (store.modules?.["team"]) {
return;
}
var ctx = {
store,
Store: cfg.Store,
pinPads: cfg.pinPads,
emit,
onReadyHandlers: {},
teams: {},
cache: {},
nocache: {},
updateMetadata: cfg.updateMetadata,
updateProgress: cfg.updateLoadingProgress,
progress: 0
};
if (!store.proxy.teams) {
store.proxy.teams = {};
}
var teams = store.proxy.teams;
ctx.numberOfTeams = Object.keys(teams).length;
ctx.store.proxy.on("change", [ "teams" ], (function(o, n, p) {
if (p[2] !== "hash") {
return;
}
updateMyRights(ctx, p[1], n);
}));
ctx.store.proxy.on("remove", [ "teams" ], (function(o, p) {
if (p[2] !== "hash") {
return;
}
updateMyRights(ctx, p[1]);
}));
var checkKeyPair = function(edPrivate, edPublic) {
if (!edPrivate || !edPublic) {
return true;
}
try {
var secretKey = Nacl.util.decodeBase64(edPrivate);
var pair = Nacl.sign.keyPair.fromSecretKey(secretKey);
return Nacl.util.encodeBase64(pair.publicKey) === edPublic;
} catch (e) {
return false;
}
};
var removeDuplicates = function() {
var _teams = {};
Object.keys(teams).forEach((function(id) {
try {
var t = teams[id];
var _t = _teams[t.channel];
var edPrivate = Util.find(t, [ "keys", "drive", "edPrivate" ]);
var edPublic = Util.find(t, [ "keys", "drive", "edPublic" ]);
if (!edPublic) {
Feedback.send("TEAM_CORRUPTED_EDPUBLIC");
} else if (edPrivate && edPublic && !checkKeyPair(edPrivate, edPublic)) {
Feedback.send("TEAM_CORRUPTED_EDPRIVATE");
delete teams[id].keys.drive.edPrivate;
edPrivate = undefined;
}
if (t.hash) {
var parsed = Hash.parseTypeHash("drive", t.hash);
if (parsed.version === 2 && t.hash.length !== 40) {
Feedback.send("TEAM_CORRUPTED_HASH");
}
}
if (!_t) {
_teams[t.channel] = id;
return;
}
var best = teams[_t];
var bestPrivate = Util.find(best, [ "keys", "drive", "edPrivate" ]);
var bestChat = Util.find(best, [ "keys", "chat", "edit" ]);
var chat = Util.find(t, [ "keys", "chat", "edit" ]);
if (!best.hash && t.hash) {
best.hash = t.hash;
}
if (!bestPrivate && edPrivate) {
best.keys.drive.edPrivate = edPrivate;
}
if (!bestChat && chat) {
best.keys.chat.edit = chat;
}
ctx.store.proxy.duplicateTeams = ctx.store.proxy.duplicateTeams || {};
ctx.store.proxy.duplicateTeams[id] = teams[id];
delete teams[id];
} catch (e) {
console.error(e);
}
}));
};
Object.keys(teams).forEach((function(id) {
ctx.onReadyHandlers[id] = [];
if (!Util.find(teams, [ id, "keys", "mailbox" ])) {
teams[id].keys.mailbox = deriveMailbox(teams[id]);
}
openChannel(ctx, teams[id], id, waitFor((function(err) {
if (err) {
delete ctx.onReadyHandlers[id];
delete ctx.cache[id];
if (err?.error === "NOCACHE") {
ctx.nocache[id] = true;
}
var txt = typeof err === "string" ? err : err.type || err.message;
Feedback.send("TEAM_LOADING_ERROR=" + txt);
return void console.error(err);
}
console.debug("Team " + id + " cache ready");
})), Cache.isEnabled());
}));
team.onReady = function(waitFor) {
removeDuplicates();
var checkTeam = function(id) {
if (!teams[id]) {
closeTeam(ctx, id);
delete ctx.onReadyHandlers[id];
return true;
}
return false;
};
Object.keys(ctx.teams).forEach(checkTeam);
Object.keys(ctx.onReadyHandlers).forEach((function(id) {
var closed = checkTeam(id);
if (closed) {
return;
}
var team = ctx.store.proxy.teams[id];
var rosterChan = Util.find(team, [ "keys", "roster", "channel" ]);
var _cb = Util.once(Util.mkAsync(waitFor()));
nThen((function(w) {
checkTeamChannels(ctx, id, team.channel, rosterChan, w, _cb);
}));
ctx.onReadyHandlers[id].push({
cb: _cb
});
}));
Object.keys(teams).forEach((function(id) {
if (ctx.onReadyHandlers[id] || ctx.teams[id]) {
return;
}
ctx.onReadyHandlers[id] = [];
if (!Util.find(teams, [ id, "keys", "mailbox" ])) {
teams[id].keys.mailbox = deriveMailbox(teams[id]);
}
openChannel(ctx, teams[id], id, waitFor((function(err) {
if (err) {
var txt = typeof err === "string" ? err : err.type || err.message;
Feedback.send("TEAM_LOADING_ERROR=" + txt);
return void console.error(err);
}
console.debug("Team " + id + " ready");
})));
}));
openCachedTeamChat();
onStoreReady.fire();
};
team.getTeam = function(id) {
return ctx.teams[id];
};
team.getTeamsData = function(app) {
var t = {};
var safe = false;
if ([ "drive", "teams", "settings" ].indexOf(app) !== -1) {
safe = true;
}
Object.keys(teams).forEach((function(id) {
if (!ctx.teams[id]) {
return;
}
var proxy = ctx.teams[id].proxy || {};
var nPads = proxy.drive && Object.keys(proxy.drive.filesData || {}).length;
var nSf = proxy.drive && Object.keys(proxy.drive.sharedFolders || {}).length;
t[id] = {
owner: teams[id].owner,
name: teams[id].metadata.name,
channel: teams[id].channel,
numberPads: nPads,
numberSf: nSf,
roster: Util.find(teams[id], [ "keys", "roster", "channel" ]),
edPublic: Util.find(teams[id], [ "keys", "drive", "edPublic" ]),
avatar: Util.find(teams[id], [ "metadata", "avatar" ]),
viewer: !Util.find(teams[id], [ "keys", "drive", "edPrivate" ]),
notifications: Util.find(teams[id], [ "keys", "mailbox", "channel" ]),
curvePublic: Util.find(teams[id], [ "keys", "mailbox", "keys", "curvePublic" ]),
validKeys: checkKeyPair(Util.find(teams[id], [ "keys", "drive", "edPrivate" ]), Util.find(teams[id], [ "keys", "drive", "edPublic" ]))
};
if (safe && ctx.teams[id]) {
t[id].secondaryKey = ctx.teams[id].secondaryKey;
}
if (ctx.teams[id]) {
t[id].hasSecondaryKey = Boolean(ctx.teams[id].secondaryKey);
}
}));
return t;
};
team.getTeams = function() {
return Object.keys(ctx.teams);
};
var isPending = function(teamId, curve) {
var team = ctx.teams[teamId];
if (!team) {
return;
}
var state = team.roster && team.roster.getState();
if (!state.members) {
return;
}
var m = state.members[curve] || {};
return m.pending;
};
team.removeFromTeam = function(teamId, curve, pendingOnly) {
if (!teams[teamId]) {
return;
}
if (pendingOnly && !isPending(teamId, curve)) {
return;
}
if (ctx.onReadyHandlers[teamId]) {
ctx.onReadyHandlers[teamId].push({
cb: function() {
ctx.teams[teamId].roster.remove([ curve ], (function(err) {
if (err && err !== "NO_CHANGE") {
console.error(err);
}
}));
}
});
return;
}
var team = ctx.teams[teamId];
if (!team) {
return void console.error("TEAM MODULE ERROR");
}
team.roster.remove([ curve ], (function(err) {
if (err && err !== "NO_CHANGE") {
console.error(err);
}
}));
};
team.changeMyRights = function(id, edit, teamData, cb) {
changeMyRights(ctx, id, edit, teamData, cb);
};
team.updateMyData = function(data) {
Object.keys(ctx.teams).forEach((function(id) {
var team = ctx.teams[id];
if (!team.roster) {
return;
}
var obj = {};
obj[data.curvePublic] = data;
team.roster.describe(obj, (function(err) {
if (err) {
console.error(err);
}
}));
}));
};
team.removeClient = function(clientId) {
removeClient(ctx, clientId);
};
var listTeams = function(cb) {
var t = Util.clone(teams);
Object.keys(t).forEach((function(id) {
if (ctx.teams[id]) {
t[id].offline = ctx.teams[id].offline;
return;
}
t[id].error = true;
if (ctx.nocache[id]) {
t[id].offline = true;
}
}));
cb(t);
};
team.execCommand = function(clientId, obj, cb) {
var cmd = obj.cmd;
var data = obj.data;
if (cmd === "SUBSCRIBE") {
return void subscribe(ctx, data, clientId, cb);
}
if (cmd === "LIST_TEAMS") {
return void listTeams(cb);
}
if (cmd === "OPEN_TEAM_CHAT") {
return void openTeamChat(ctx, data, clientId, cb);
}
if (cmd === "GET_TEAM_ROSTER") {
return void getTeamRoster(ctx, data, clientId, cb);
}
if (cmd === "GET_TEAM_METADATA") {
return void getTeamMetadata(ctx, data, clientId, cb);
}
if (cmd === "SET_TEAM_METADATA") {
return void setTeamMetadata(ctx, data, clientId, cb);
}
if (cmd === "OFFER_OWNERSHIP") {
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
return void offerOwnership(ctx, data, clientId, cb);
}
if (cmd === "ANSWER_OWNERSHIP") {
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
return void answerOwnership(ctx, data, clientId, cb);
}
if (cmd === "DESCRIBE_USER") {
return void describeUser(ctx, data, clientId, cb);
}
if (cmd === "INVITE_TO_TEAM") {
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
return void inviteToTeam(ctx, data, clientId, cb);
}
if (cmd === "LEAVE_TEAM") {
return void leaveTeam(ctx, data, clientId, cb);
}
if (cmd === "JOIN_TEAM") {
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
return void joinTeam(ctx, data, clientId, cb);
}
if (cmd === "REMOVE_USER") {
return void removeUser(ctx, data, clientId, cb);
}
if (cmd === "DELETE_TEAM") {
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
return void deleteTeam(ctx, data, clientId, cb);
}
if (cmd === "CREATE_TEAM") {
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
return void createTeam(ctx, data, clientId, cb);
}
if (cmd === "GET_EDITABLE_FOLDERS") {
return void getEditableFolders(ctx, data, clientId, cb);
}
if (cmd === "CREATE_INVITE_LINK") {
return void createInviteLink(ctx, data, clientId, cb);
}
if (cmd === "GET_PREVIEW_CONTENT") {
return void getPreviewContent(ctx, data, clientId, cb);
}
if (cmd === "ACCEPT_LINK_INVITATION") {
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
return void acceptLinkInvitation(ctx, data, clientId, cb);
}
};
return team;
};
Team.anonGetPreviewContent = function(cfg, data, cb) {
getPreviewContent(cfg, data, null, cb);
};
return Team;
};
if (module.exports) {
module.exports = factory(requireCommonUtil(), requireCommonHash(), requireCommonConstants(), requireCommonRealtime(), requireProxyManager(), requireUserObject(), requireSharedfolder(), requireRoster(), requireCommonMessaging(), requireCommonFeedback(), requireInvitation(), requireCryptget(), requireCacheStore(), requirePinpad(), requireChainpadListmap(), requireCrypto(), requireChainpadNetflux(), requireChainpad_dist(), requireNthen(), requireNaclFast());
}
})();
})(team);
return team.exports;
}
var messenger = {
exports: {}
};
var hasRequiredMessenger;
function requireMessenger() {
if (hasRequiredMessenger) return messenger.exports;
hasRequiredMessenger = 1;
(function(module) {
(() => {
const factory = (Crypto, Hash, Util, Realtime, Messaging, Constants, Messages = {}, PadTypes, nThen) => {
var Curve = Crypto.Curve;
var Msg = {};
Msg.setCustomize = data => {
Messages = data.Messages;
};
var Types = {
message: "MSG",
unfriend: "UNFRIEND",
mapId: "MAP_ID",
mapIdAck: "MAP_ID_ACK"
};
var clone = function(o) {
return JSON.parse(JSON.stringify(o));
};
var convertToUint8 = function(obj) {
var l = Object.keys(obj).length;
var u = new Uint8Array(l);
for (var i = 0; i < l; i++) {
u[i] = obj[i];
}
return u;
};
var createData = Messaging.createData;
var getFriend = function(proxy, pubkey) {
if (pubkey === proxy.curvePublic) {
var data = createData(proxy);
delete data.channel;
return data;
}
return proxy.friends ? proxy.friends[pubkey] : undefined;
};
var getFriendList = Msg.getFriendList = function(proxy) {
if (!proxy.friends) {
proxy.friends = {};
}
return proxy.friends;
};
var msgAlreadyKnown = function(channel, sig) {
return channel.messages.some((function(message) {
return message.sig === sig;
}));
};
var getFriendFromChannel = function(ctx, id) {
var proxy = ctx.store.proxy;
var friends = getFriendList(proxy);
var friend;
for (var k in friends) {
if (friends[k].channel === id) {
friend = friends[k];
break;
}
}
return friend;
};
var initRangeRequest = function(ctx, txid, chanId, cb) {
if (!ctx.range_requests) {
ctx.range_requests = {};
}
ctx.range_requests[txid] = {
messages: [],
cb,
chanId
};
};
var getRangeRequest = function(ctx, txid) {
return ctx.range_requests[txid];
};
var deleteRangeRequest = function(ctx, txid) {
delete ctx.range_requests[txid];
};
var getMoreHistory = function(ctx, chanId, hash, count, cb) {
if (typeof cb !== "function") {
return;
}
if (typeof hash !== "string") {
return void cb([]);
}
var chan = ctx.channels[chanId];
if (typeof chan === "undefined") {
console.error("chan is undefined. we're going to have a problem here");
return;
}
var txid = Util.uid();
initRangeRequest(ctx, txid, chanId, cb);
var msg = [ "GET_HISTORY_RANGE", chan.id, {
from: hash,
count,
txid
} ];
var network = ctx.store.network;
network.sendto(network.historyKeeper, JSON.stringify(msg)).then((function() {}), (function(err) {
console.error(err);
}));
};
var getChannelMessagesSince = function(ctx, channel, data, keys) {
var network = ctx.store.network;
console.log("Fetching [%s] messages since [%s]", channel.id, data.lastKnownHash || "");
if (channel.isPadChat || channel.isTeamChat) {
var txid = Util.uid();
initRangeRequest(ctx, txid, channel.id, undefined);
var msg0 = [ "GET_HISTORY_RANGE", channel.id, {
count: 10,
txid
} ];
network.sendto(network.historyKeeper, JSON.stringify(msg0)).then((function() {}), (function(err) {
console.error(err);
}));
return;
}
var proxy = ctx.store.proxy;
var friend = getFriendFromChannel(ctx, channel.id) || {};
var cfg = {
metadata: {
validateKey: keys ? keys.validateKey : undefined,
owners: [ proxy.edPublic, friend.edPublic ]
},
lastKnownHash: data.lastKnownHash
};
var msg = [ "GET_HISTORY", channel.id, cfg ];
network.sendto(network.historyKeeper, JSON.stringify(msg)).then((function() {}), (function(err) {
console.error(err);
}));
};
var setChannelHead = function(ctx, id, hash, cb) {
var channel = ctx.channels[id];
if (channel.isFriendChat) {
var friend = getFriendFromChannel(ctx, id);
if (!friend) {
return void cb({
error: "NO_SUCH_FRIEND"
});
}
friend.lastKnownHash = hash;
} else if (channel.isPadChat) ; else if (channel.isTeamChat) ; else {
return void cb({
error: "NOT_IMPLEMENTED"
});
}
cb();
};
var onChannelReady = function(ctx, chanId) {
var channel = ctx.channels[chanId];
if (!channel) {
return;
}
channel.ready = true;
channel.onReady.fire();
};
var onIdMessage = function(ctx, msg, sender) {
var channel, parsed0;
try {
parsed0 = JSON.parse(msg);
channel = ctx.channels[parsed0.channel];
if (!channel || channel.wc.members.indexOf(sender) === -1) {
return;
}
} catch (e) {
return void console.error(e, msg);
}
var decryptedMsg = channel.decrypt(parsed0.msg);
if (!decryptedMsg) {
return void console.error("Failed to decrypt message");
}
var parsed = Util.tryParse(decryptedMsg);
if (!parsed) {
return void console.error(decryptedMsg);
}
if (parsed[0] !== Types.mapId && parsed[0] !== Types.mapIdAck) {
return;
}
if (parsed[2] !== sender || !parsed[1]) {
return;
}
channel.mapId[sender] = parsed[1];
ctx.emit("JOIN", {
info: parsed[1],
id: channel.id
}, channel.clients);
if (channel.readOnly) {
return;
}
if (parsed[0] !== Types.mapId) {
return;
}
var proxy = ctx.store.proxy || {};
var myData = createData(proxy);
delete myData.channel;
var rMsg = [ Types.mapIdAck, myData, channel.wc.myID ];
var rMsgStr = JSON.stringify(rMsg);
var cryptMsg = channel.encrypt(rMsgStr);
var data = {
channel: channel.id,
msg: cryptMsg
};
var network = ctx.store.network;
network.sendto(sender, JSON.stringify(data));
};
var orderMessages = function(channel, new_messages) {
var messages = channel.messages;
new_messages.reverse().forEach((function(msg) {
messages.unshift(msg);
}));
};
var removeFromFriendList = function(ctx, curvePublic, cb) {
var proxy = ctx.store.proxy;
var friends = proxy.friends;
if (!friends) {
return;
}
delete friends[curvePublic];
Realtime.whenRealtimeSyncs(ctx.store.realtime, (function() {
ctx.updateMetadata();
cb();
}));
};
var pushMsg = function(ctx, channel, cryptMsg) {
var sig = cryptMsg.slice(0, 64);
if (msgAlreadyKnown(channel, sig)) {
return;
}
var msg = channel.decrypt(cryptMsg);
var parsedMsg = JSON.parse(msg);
var curvePublic;
if (parsedMsg[0] === Types.message) {
var res = {
type: parsedMsg[0],
sig,
author: parsedMsg[1],
time: parsedMsg[2],
text: parsedMsg[3],
channel: channel.id,
name: parsedMsg[4]
};
channel.messages.push(res);
if (channel.ready) {
ctx.emit("MESSAGE", res, channel.clients);
}
return true;
}
var proxy = ctx.store.proxy;
if (parsedMsg[0] === Types.unfriend) {
curvePublic = parsedMsg[1];
if (curvePublic === proxy.curvePublic) {
return;
}
removeFromFriendList(ctx, curvePublic, (function() {
channel.wc.leave(Types.unfriend);
var network = ctx.store.network;
if (channel.onReconnect) {
network.off("reconnect", channel.onReconnect);
}
delete ctx.channels[channel.id];
ctx.emit("UNFRIEND", {
curvePublic,
fromMe: false
}, channel.clients);
}));
return;
}
};
var onDirectMessage = function(ctx, msg, sender) {
var hk = ctx.store.network.historyKeeper;
if (sender !== hk) {
return void onIdMessage(ctx, msg, sender);
}
var parsed = JSON.parse(msg);
if ((parsed.validateKey || parsed.owners) && parsed.channel) {
return;
}
var channel;
if (/HISTORY_RANGE/.test(parsed[0])) {
var txid = parsed[1];
var req = getRangeRequest(ctx, txid);
var type = parsed[0];
if (!req) {
return;
}
channel = ctx.channels[req.chanId];
if (!channel) {
return;
}
if (!req.cb) {
if (type === "HISTORY_RANGE") {
if (!Array.isArray(parsed[2])) {
return;
}
pushMsg(ctx, channel, parsed[2][4]);
} else if (type === "HISTORY_RANGE_END") {
onChannelReady(ctx, req.chanId);
return deleteRangeRequest(ctx, txid);
}
return;
}
if (type === "HISTORY_RANGE") {
req.messages.push(parsed[2]);
} else if (type === "HISTORY_RANGE_END") {
var decrypted = req.messages.map((function(msg) {
if (msg[2] !== "MSG") {
return;
}
try {
return {
d: JSON.parse(channel.decrypt(msg[4])),
sig: msg[4].slice(0, 64)
};
} catch (e) {
return void console.log("failed to decrypt");
}
})).filter((function(decrypted) {
if (!decrypted || !decrypted.d || decrypted.d[0] !== Types.message) {
return;
}
if (msgAlreadyKnown(channel, decrypted.sig)) {
return;
}
return decrypted;
})).map((function(O) {
return {
type: O.d[0],
sig: O.sig,
author: O.d[1],
time: O.d[2],
text: O.d[3],
channel: req.chanId,
name: O.d[4]
};
}));
orderMessages(channel, decrypted);
req.cb(decrypted);
return deleteRangeRequest(ctx, txid);
} else {
console.log(parsed);
}
return;
}
if (parsed.channel && ctx.channels[parsed.channel]) {
channel = ctx.channels[parsed.channel];
if (parsed.error === "ECLEARED") {
setChannelHead(ctx, parsed.channel, "", (function() {}));
channel.messages = [];
ctx.emit("CLEAR_CHANNEL", parsed.channel, channel.clients);
return;
}
if (parsed.error && (parsed.error === "EINVAL" || parsed.error === "EUNKNOWN")) {
setChannelHead(ctx, parsed.channel, "", (function() {
getChannelMessagesSince(ctx, channel, {}, {});
}));
return;
}
if (parsed.state && parsed.state === 1 && parsed.channel) {
return void onChannelReady(ctx, parsed.channel);
}
}
channel = ctx.channels[parsed[3]];
if (!channel) {
return;
}
pushMsg(ctx, channel, parsed[4]);
};
var onMessage = function(ctx, msg, sender, chan) {
var channel = ctx.channels[chan.id];
if (!channel) {
return;
}
pushMsg(ctx, channel, msg);
};
var onFriendRemoved = function(ctx, curvePublic, chanId) {
var channel = ctx.channels[chanId];
if (!channel) {
return;
}
if (channel.wc) {
channel.wc.leave(Types.unfriend);
}
var network = ctx.store.network;
if (channel.onReconnect) {
network.off("reconnect", channel.onReconnect);
}
delete ctx.channels[channel.id];
ctx.emit("UNFRIEND", {
curvePublic,
fromMe: true
}, ctx.friendsClients);
};
var removeFriend = function(ctx, curvePublic, _cb) {
var cb = Util.once(_cb);
if (typeof cb !== "function") {
return void console.error("NO_CALLBACK");
}
var proxy = ctx.store.proxy;
var data = getFriend(proxy, curvePublic);
if (!data) {
console.error("friend is not valid");
return void cb({
error: "INVALID_FRIEND"
});
}
var channel = ctx.channels[data.channel];
if (ctx.store.mailbox && data.curvePublic && data.notifications) {
Messaging.removeFriend(ctx.store, curvePublic, (function(obj) {
if (obj && obj.error) {
return void cb({
error: obj.error
});
}
ctx.updateMetadata();
cb(obj);
}));
return;
}
if (!channel) {
return void cb({
error: "NO_SUCH_CHANNEL"
});
}
try {
var msg = [ Types.unfriend, proxy.curvePublic, +new Date ];
var msgStr = JSON.stringify(msg);
var cryptMsg = channel.encrypt(msgStr);
channel.wc.bcast(cryptMsg).then((function() {
onFriendRemoved(ctx, curvePublic, data.channel);
removeFromFriendList(ctx, curvePublic, (function() {
cb();
}));
}), (function(err) {
if (err) {
return void cb({
error: err
});
}
onFriendRemoved(ctx, curvePublic, data.channel);
removeFromFriendList(ctx, curvePublic, (function() {
cb();
}));
}));
} catch (e) {
cb({
error: e
});
}
};
var cancelFriend = function(ctx, data, _cb) {
var cb = Util.once(_cb);
if (typeof cb !== "function") {
return void console.error("NO_CALLBACK");
}
ctx.Store.cancelFriendRequest(data, cb);
};
var getAllClients = function(ctx) {
var all = [];
Array.prototype.push.apply(all, ctx.friendsClients);
Object.keys(ctx.channels).forEach((function(id) {
Array.prototype.push.apply(all, ctx.channels[id].clients);
}));
return Util.deduplicateString(all);
};
var muteUser = function(ctx, data, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var proxy = ctx.store.proxy;
var muted = proxy.mutedUsers = proxy.mutedUsers || {};
if (muted[data.curvePublic]) {
return void cb();
}
muted[data.curvePublic] = data;
ctx.emit("UPDATE_MUTED", null, getAllClients(ctx));
cb();
};
var unmuteUser = function(ctx, curvePublic, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var proxy = ctx.store.proxy;
var muted = proxy.mutedUsers = proxy.mutedUsers || {};
delete muted[curvePublic];
ctx.emit("UPDATE_MUTED", null, getAllClients(ctx));
cb(Object.keys(muted).length);
};
var getMutedUsers = function(ctx, cb) {
var proxy = ctx.store.proxy;
if (cb) {
return void cb(proxy.mutedUsers || {});
}
return proxy.mutedUsers || {};
};
var openChannel = function(ctx, data) {
var proxy = ctx.store.proxy;
var network = ctx.store.network;
var hk = network.historyKeeper;
var keys = data.keys;
var encryptor = data.encryptor || Curve.createEncryptor(keys);
var channel = {
id: data.channel,
isFriendChat: data.isFriendChat,
isPadChat: data.isPadChat,
isTeamChat: data.isTeamChat,
padChan: data.padChan,
readOnly: data.readOnly,
ready: false,
onReady: Util.mkEvent(true),
sending: false,
messages: [],
clients: data.clients || [],
onUserlistUpdate: data.onUserlistUpdate || function() {},
mapId: {}
};
if (data.onReady) {
channel.onReady.reg(data.onReady);
}
channel.encrypt = function(msg) {
if (channel.readOnly) {
return;
}
return encryptor.encrypt(msg);
};
channel.decrypt = data.decrypt || function(msg) {
return encryptor.decrypt(msg);
};
var onJoining = function(peer) {
if (peer === hk) {
return;
}
if (channel.readOnly) {
return;
}
if (channel.isPadChat) {
return;
}
var myData = createData(proxy);
delete myData.channel;
var msg = [ Types.mapId, myData, channel.wc.myID ];
var msgStr = JSON.stringify(msg);
var cryptMsg = channel.encrypt(msgStr);
var data = {
channel: channel.id,
msg: cryptMsg
};
network.sendto(peer, JSON.stringify(data));
};
var onLeaving = function(peer) {
if (peer === hk) {
return;
}
var otherData = channel.mapId[peer];
if (!otherData) {
return;
}
if (channel.wc.members.some((function(nId) {
return channel.mapId[nId] && channel.mapId[nId].curvePublic === otherData.curvePublic;
}))) {
return;
}
ctx.emit("LEAVE", {
info: otherData,
id: channel.id
}, channel.clients);
};
var onOpen = function(chan) {
channel.wc = chan;
ctx.channels[data.channel] = channel;
chan.on("message", (function(msg, sender) {
onMessage(ctx, msg, sender, chan);
}));
chan.on("join", onJoining);
chan.on("leave", onLeaving);
getChannelMessagesSince(ctx, channel, data, keys);
};
network.join(data.channel).then(onOpen, (function(err) {
console.error(err);
}));
channel.onReconnect = function() {
if (channel && channel.stopped) {
return;
}
if (!ctx.channels[data.channel]) {
return;
}
network.join(data.channel).then(onOpen, (function(err) {
console.error(err);
}));
};
network.on("reconnect", channel.onReconnect);
};
var sendMessage = function(ctx, id, payload, cb) {
var channel = ctx.channels[id];
if (!channel) {
return void cb({
error: "NO_CHANNEL"
});
}
if (channel.readOnly) {
return void cb({
error: "FORBIDDEN"
});
}
var network = ctx.store.network;
if (!network.webChannels.some((function(wc) {
if (wc.id === channel.wc.id) {
return true;
}
}))) {
return void cb({
error: "NO_SUCH_CHANNEL"
});
}
var proxy = ctx.store.proxy || {};
var msg = [ Types.message, proxy.curvePublic, +new Date, payload ];
if (!channel.isFriendChat) {
var name = proxy[Constants.displayNameKey] || Messages.anonymous + "#" + (proxy.uid || ctx.store.noDriveUid).slice(0, 5);
msg.push(name);
}
var msgStr = JSON.stringify(msg);
var cryptMsg = channel.encrypt(msgStr);
channel.wc.bcast(cryptMsg).then((function() {
pushMsg(ctx, channel, cryptMsg);
cb();
}), (function(err) {
cb({
error: err
});
}));
};
var getOnlineList = function(ctx, chanId) {
var channel = ctx.channels[chanId];
if (!channel) {
return;
}
var online = [];
var myData = createData(ctx.store.proxy, false);
online.push(myData.curvePublic);
channel.wc.members.forEach((function(nId) {
if (nId === ctx.store.network.historyKeeper) {
return;
}
var data = channel.mapId[nId] || {};
if (!data.curvePublic) {
return;
}
if (online.indexOf(data.curvePublic) !== -1) {
return;
}
online.push(data.curvePublic);
}));
return online;
};
var getStatus = function(ctx, chanId, cb) {
var channel = ctx.channels[chanId];
if (!channel) {
return void cb("NO_SUCH_CHANNEL");
}
if (channel.onUserlistUpdate) {
channel.onUserlistUpdate();
}
var proxy = ctx.store.proxy || {};
var online = channel.wc.members.some((function(nId) {
if (nId === ctx.store.network.historyKeeper) {
return;
}
var data = channel.mapId[nId] || undefined;
if (!data) {
return false;
}
return data.curvePublic !== proxy.curvePublic;
}));
cb(online);
};
var getMyInfo = function(ctx, cb) {
var proxy = ctx.store.proxy || {};
cb({
curvePublic: proxy.curvePublic,
displayName: proxy[Constants.displayNameKey]
});
};
var loadFriend = function(ctx, clientId, friend, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var chanId = friend.channel;
var channel = ctx.channels[chanId];
if (channel) {
return void channel.onReady.reg((function() {
if (channel.clients.indexOf(clientId) === -1) {
channel.clients.push(clientId);
}
cb();
}));
}
var proxy = ctx.store.proxy;
var keys = Curve.deriveKeys(friend.curvePublic, proxy.curvePrivate);
var data = {
keys,
channel: friend.channel,
lastKnownHash: friend.lastKnownHash,
owners: [ proxy.edPublic, friend.edPublic ],
isFriendChat: true,
clients: clientId ? [ clientId ] : ctx.friendsClients,
onReady: cb
};
openChannel(ctx, data);
};
var initFriends = function(ctx, clientId, cb) {
var friends = getFriendList(ctx.store.proxy);
nThen((function(waitFor) {
Object.keys(friends).forEach((function(key) {
if (key === "me") {
delete friends.me.channel;
return;
}
var friend = clone(friends[key]);
if (typeof friend !== "object") {
return;
}
if (!friend.channel) {
return;
}
loadFriend(ctx, clientId, friend, waitFor());
}));
})).nThen((function() {
if (ctx.friendsClients.indexOf(clientId) === -1) {
ctx.friendsClients.push(clientId);
}
cb();
}));
};
var getRooms = function(ctx, data, cb) {
var proxy = ctx.store.proxy;
if (data && data.curvePublic) {
var curvePublic = data.curvePublic;
var friend = getFriend(proxy, curvePublic);
if (!friend) {
return void cb({
error: "NO_SUCH_FRIEND"
});
}
var channel = ctx.channels[friend.channel];
if (!channel) {
return void cb({
error: "NO_SUCH_CHANNEL"
});
}
return void cb([ {
id: channel.id,
isFriendChat: true,
name: friend.displayName,
lastKnownHash: friend.lastKnownHash,
curvePublic: friend.curvePublic,
messages: channel.messages
} ]);
}
if (data && data.padChat) {
var pCChannel = ctx.channels[data.padChat];
if (!pCChannel) {
return void cb({
error: "NO_SUCH_CHANNEL"
});
}
return void cb([ {
id: pCChannel.id,
isPadChat: true,
messages: pCChannel.messages
} ]);
}
if (data && data.teamChat) {
var tCChannel = ctx.channels[data.teamChat];
if (!tCChannel) {
return void cb({
error: "NO_SUCH_CHANNEL"
});
}
return void cb([ {
id: tCChannel.id,
isTeamChat: true,
messages: tCChannel.messages
} ]);
}
var rooms = Object.keys(ctx.channels).map((function(id) {
var r = ctx.channels[id];
var name, lastKnownHash, curvePublic;
if (r.isFriendChat) {
var friend = getFriendFromChannel(ctx, id);
if (!friend) {
return null;
}
name = friend.displayName;
lastKnownHash = friend.lastKnownHash;
curvePublic = friend.curvePublic;
} else if (r.isPadChat) {
return;
} else if (r.isTeamChat) {
return;
} else ;
return {
id: r.id,
isFriendChat: r.isFriendChat,
name,
lastKnownHash,
curvePublic,
messages: r.messages
};
})).filter((function(x) {
return x;
}));
cb(rooms);
};
var getUserList = function(ctx, data, cb) {
var room = ctx.channels[data.id];
if (!room) {
return void cb({
error: "NO_SUCH_CHANNEL"
});
}
if (room.isFriendChat) {
var friend = getFriendFromChannel(ctx, data.id);
if (!friend) {
return void cb({
error: "NO_SUCH_FRIEND"
});
}
cb([ friend ]);
} else {
cb([]);
}
};
var openPadChat = function(ctx, clientId, data, _cb) {
var chanId = data.channel;
var cb = Util.once(Util.mkAsync((function() {
ctx.emit("PADCHAT_READY", chanId, [ clientId ]);
_cb();
})));
var channel = ctx.channels[chanId];
if (channel) {
return void channel.onReady.reg((function() {
if (channel.clients.indexOf(clientId) === -1) {
channel.clients.push(clientId);
}
cb();
}));
}
var secret = data.secret;
if (secret.keys.cryptKey) {
secret.keys.cryptKey = convertToUint8(secret.keys.cryptKey);
}
var encryptor = Crypto.createEncryptor(secret.keys);
var vKey = secret.keys && secret.keys.validateKey || ctx.validateKeys[secret.channel];
var chanData = {
padChan: data.secret && data.secret.channel,
readOnly: typeof secret.keys === "object" && !secret.keys.validateKey,
encryptor,
channel: data.channel,
isPadChat: true,
decrypt: function(msg) {
return encryptor.decrypt(msg, vKey);
},
clients: [ clientId ],
onReady: cb
};
openChannel(ctx, chanData);
};
var openTeamChat = function(ctx, clientId, data, onUpdate, _cb) {
var chatData = data;
var chanId = chatData.channel;
var secret = chatData.secret;
if (!chanId || !secret) {
return void _cb({
error: "EINVAL"
});
}
var cb = Util.once(Util.mkAsync((function() {
ctx.emit("TEAMCHAT_READY", chanId, [ clientId ]);
_cb({
readOnly: typeof secret.keys === "object" && !secret.keys.validateKey,
channel: chanId
});
})));
var channel = ctx.channels[chanId];
if (channel) {
return void channel.onReady.reg((function() {
if (channel.clients.indexOf(clientId) === -1) {
channel.clients.push(clientId);
}
cb();
}));
}
if (secret.keys.cryptKey) {
secret.keys.cryptKey = convertToUint8(secret.keys.cryptKey);
}
var encryptor = Crypto.createEncryptor(secret.keys);
var vKey = secret.keys && secret.keys.validateKey || chatData.validateKey;
var chanData = {
teamId: data.teamId,
readOnly: typeof secret.keys === "object" && !secret.keys.validateKey,
encryptor,
channel: chanId,
isTeamChat: true,
decrypt: function(msg) {
return encryptor.decrypt(msg, vKey);
},
clients: [ clientId ],
onUserlistUpdate: onUpdate,
onReady: cb
};
openChannel(ctx, chanData);
};
var clearOwnedChannel = function(ctx, id, cb) {
var channel = ctx.channels[id];
if (!channel) {
return void cb({
error: "NO_CHANNEL"
});
}
if (!ctx.store.rpc) {
return void cb({
error: "RPC_NOT_READY"
});
}
ctx.store.rpc.clearOwnedChannel(id, (function(err) {
cb({
error: err
});
if (!err) {
channel.messages = [];
ctx.emit("CLEAR_CHANNEL", id, channel.clients);
}
}));
};
var removeClient = function(ctx, cId) {
var friendsIdx = ctx.friendsClients.indexOf(cId);
if (friendsIdx !== -1) {
ctx.friendsClients.splice(friendsIdx, 1);
}
Object.keys(ctx.channels).forEach((function(id) {
var channel = ctx.channels[id];
var clients = channel.clients;
var idx = clients.indexOf(cId);
if (idx !== -1) {
clients.splice(idx, 1);
}
if (clients.length === 0) {
if (channel.wc) {
channel.wc.leave();
}
var network = ctx.store.network;
if (channel.onReconnect) {
network.off("reconnect", channel.onReconnect);
}
channel.stopped = true;
delete ctx.channels[id];
return true;
}
}));
};
Msg.init = function(cfg, waitFor, emit) {
var messenger = {};
var store = cfg.store;
if (store.messenger) {
store.messenger.addListener();
return store.messenger;
}
if (!PadTypes.isAvailable("contacts")) {
return;
}
var ctx = {
store,
Store: cfg.Store,
updateMetadata: cfg.updateMetadata,
pinPads: cfg.pinPads,
emit,
friendsClients: [],
channels: {},
validateKeys: {},
range_requests: {}
};
messenger.addListener = function() {
if (store.proxy) {
store.proxy.on("change", [ "mutedUsers" ], (function() {
ctx.emit("UPDATE_MUTED", null, getAllClients(ctx));
}));
}
};
messenger.addListener();
let onNetwork = Util.once((_network => {
const network = ctx.store.network || _network;
network.on("message", (function(msg, sender) {
onDirectMessage(ctx, msg, sender);
}));
network.on("disconnect", (function() {
ctx.emit("DISCONNECT", null, getAllClients(ctx));
}));
network.on("reconnect", (function() {
ctx.emit("RECONNECT", null, getAllClients(ctx));
}));
}));
store.networkPromise?.then(onNetwork);
if (ctx.store.network) {
onNetwork();
}
messenger.onFriendUpdate = function(curve) {
var friend = getFriend(store.proxy, curve);
if (!friend || !friend.channel) {
return;
}
var chan = ctx.channels[friend.channel];
if (chan) {
ctx.emit("UPDATE_DATA", {
info: clone(friend),
channel: friend.channel
}, chan.clients);
}
};
messenger.onFriendAdded = function(friendData) {
if (!ctx.friendsClients.length) {
return;
}
var friend = getFriend(ctx.store.proxy, friendData.curvePublic);
if (typeof friend !== "object") {
return;
}
var channel = friend.channel;
if (!channel) {
return;
}
var chanId = friend.channel;
var chan = ctx.channels[chanId];
if (chan) {
return;
}
loadFriend(ctx, null, friend, (function() {
emit("FRIEND", {
curvePublic: friend.curvePublic
}, ctx.friendsClients);
}));
};
messenger.onFriendRemoved = function(curvePublic, chanId) {
onFriendRemoved(ctx, curvePublic, chanId);
};
messenger.getOnlineList = function(chanId) {
return getOnlineList(ctx, chanId);
};
messenger.storeValidateKey = function(chan, key) {
ctx.validateKeys[chan] = key;
};
messenger.leavePad = function(padChan) {
delete ctx.validateKeys[padChan];
Object.keys(ctx.channels).some((function(chatChan) {
var channel = ctx.channels[chatChan];
if (channel.padChan !== padChan) {
return;
}
if (channel.wc) {
channel.wc.leave();
}
var network = ctx.store.network;
if (channel.onReconnect) {
network.off("reconnect", channel.onReconnect);
}
channel.stopped = true;
delete ctx.channels[chatChan];
return true;
}));
};
messenger.openTeamChat = function(data, onUpdate, cId, cb) {
openTeamChat(ctx, cId, data, onUpdate, cb);
};
messenger.removeClient = function(clientId) {
removeClient(ctx, clientId);
};
messenger.execCommand = function(clientId, obj, cb) {
var cmd = obj.cmd;
var data = obj.data;
if (cmd === "INIT_FRIENDS") {
return void initFriends(ctx, clientId, cb);
}
if (cmd === "GET_ROOMS") {
return void getRooms(ctx, data, cb);
}
if (cmd === "GET_MUTED_USERS") {
return void getMutedUsers(ctx, cb);
}
if (cmd === "GET_USERLIST") {
return void getUserList(ctx, data, cb);
}
if (cmd === "OPEN_PAD_CHAT") {
return void openPadChat(ctx, clientId, data, cb);
}
if (cmd === "GET_MY_INFO") {
return void getMyInfo(ctx, cb);
}
if (cmd === "REMOVE_FRIEND") {
return void removeFriend(ctx, data, cb);
}
if (cmd === "CANCEL_FRIEND") {
return void cancelFriend(ctx, data, cb);
}
if (cmd === "MUTE_USER") {
return void muteUser(ctx, data, cb);
}
if (cmd === "UNMUTE_USER") {
return void unmuteUser(ctx, data, cb);
}
if (cmd === "GET_STATUS") {
return void getStatus(ctx, data, cb);
}
if (cmd === "GET_MORE_HISTORY") {
return void getMoreHistory(ctx, data.id, data.sig, data.count, cb);
}
if (cmd === "SEND_MESSAGE") {
return void sendMessage(ctx, data.id, data.content, cb);
}
if (cmd === "SET_CHANNEL_HEAD") {
return void setChannelHead(ctx, data.id, data.sig, cb);
}
if (cmd === "CLEAR_OWNED_CHANNEL") {
return void clearOwnedChannel(ctx, data, cb);
}
};
return messenger;
};
return Msg;
};
if (module.exports) {
module.exports = factory(requireCrypto(), requireCommonHash(), requireCommonUtil(), requireCommonRealtime(), requireCommonMessaging(), requireCommonConstants(), undefined, requirePadTypes(), requireNthen());
}
})();
})(messenger);
return messenger.exports;
}
var history = {
exports: {}
};
var hasRequiredHistory;
function requireHistory() {
if (hasRequiredHistory) return history.exports;
hasRequiredHistory = 1;
(function(module) {
(() => {
const factory = (Util, Hash, UserObject, nThen) => {
var History = {};
var commands = {};
var getAccountChannels = function(ctx) {
var channels = [];
var edPublic = Util.find(ctx.store, [ "proxy", "edPublic" ]);
var driveOwned = (Util.find(ctx.store, [ "driveMetadata", "owners" ]) || []).indexOf(edPublic) !== -1;
if (driveOwned) {
channels.push(ctx.store.driveChannel);
}
var profile = ctx.store.proxy.profile;
if (profile) {
var profileChan = profile.edit ? Hash.hrefToHexChannelId("/profile/#" + profile.edit, null) : null;
if (profileChan) {
channels.push(profileChan);
}
}
if (ctx.store.proxy.todo) {
channels.push(Hash.hrefToHexChannelId("/todo/#" + ctx.store.proxy.todo, null));
}
var mailboxes = ctx.store.proxy.mailboxes;
if (mailboxes) {
var mList = Object.keys(mailboxes).map((function(m) {
return {
lastKnownHash: mailboxes[m].lastKnownHash,
channel: mailboxes[m].channel
};
}));
Array.prototype.push.apply(channels, mList);
}
var sf = ctx.store.proxy[UserObject.SHARED_FOLDERS];
if (sf) {
var sfChannels = Object.keys(sf).map((function(fId) {
var data = sf[fId];
if (!data || !data.owners) {
return;
}
var isOwner = Array.isArray(data.owners) && data.owners.indexOf(edPublic) !== -1;
if (!isOwner) {
return;
}
return data.channel;
})).filter(Boolean);
Array.prototype.push.apply(channels, sfChannels);
}
return channels;
};
let getTeamChannels = function(ctx, teamId) {
let team = Util.find(ctx.store, [ "proxy", "teams", teamId ]);
if (!team) {
return [];
}
let channels = [ team.channel ];
let roster = team.keys.roster;
channels.push({
channel: roster.channel,
lastKnownHash: roster.lastKnownHash
});
return channels;
};
var getEdPublic = function(ctx, teamId) {
if (!teamId) {
return Util.find(ctx.store, [ "proxy", "edPublic" ]);
}
var teamData = Util.find(ctx, [ "store", "proxy", "teams", teamId ]);
return Util.find(teamData, [ "keys", "drive", "edPublic" ]);
};
var getRpc = function(ctx, teamId) {
if (!teamId) {
return ctx.store.rpc;
}
var teams = ctx.store.modules["team"];
if (!teams) {
return;
}
var team = teams.getTeam(teamId);
if (!team) {
return;
}
return team.rpc;
};
var getHistoryData = function(ctx, channel, lastKnownHash, teamId, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var edPublic = getEdPublic(ctx, teamId);
var Store = ctx.Store;
var total = 0;
var history = 0;
var metadata = 0;
var hash;
nThen((function(waitFor) {
Store.getFileSize(null, {
channel
}, waitFor((function(obj) {
if (obj && obj.error) {
waitFor.abort();
return void cb(obj);
}
if (typeof obj.size === "undefined") {
waitFor.abort();
return void cb({
error: "ENOENT"
});
}
total = obj.size;
})));
Store.getHistory(null, {
channel,
lastKnownHash
}, waitFor((function(obj) {
if (obj && obj.error) {
waitFor.abort();
return void cb(obj);
}
if (!Array.isArray(obj)) {
waitFor.abort();
return void cb({
error: "EINVAL"
});
}
if (!obj.length) {
return;
}
hash = obj[0].hash;
var messages = obj.map((function(data) {
return data.msg;
}));
history = messages.join("\n").length;
})), true);
Store.getPadMetadata(null, {
channel
}, waitFor((function(obj) {
if (obj && obj.error) {
return;
}
if (!obj || typeof obj !== "object") {
return;
}
metadata = JSON.stringify(obj).length;
if (!obj || !Array.isArray(obj.owners) || obj.owners.indexOf(edPublic) === -1) {
waitFor.abort();
return void cb({
error: "INSUFFICIENT_PERMISSIONS"
});
}
})));
})).nThen((function() {
cb({
size: total - metadata - history,
hash
});
}));
};
commands.GET_HISTORY_SIZE = function(ctx, data, cId, cb) {
if (!ctx.store.loggedIn || !ctx.store.rpc) {
return void cb({
error: "INSUFFICIENT_PERMISSIONS"
});
}
var channels = data.channels;
if (!Array.isArray(channels)) {
return void cb({
error: "EINVAL"
});
}
var warning = [];
if (data.account) {
channels = getAccountChannels(ctx);
} else if (data.team) {
channels = getTeamChannels(ctx, data.team);
}
var size = 0;
var res = [];
nThen((function(waitFor) {
channels.forEach((function(chan) {
var channel = chan;
var lastKnownHash;
if (typeof chan === "object" && chan.channel) {
channel = chan.channel;
lastKnownHash = chan.lastKnownHash;
}
getHistoryData(ctx, channel, lastKnownHash, data.teamId, waitFor((function(obj) {
if (obj && obj.error) {
warning.push(obj.error);
return;
}
size += obj.size;
if (!obj.hash) {
return;
}
res.push({
channel,
hash: obj.hash
});
})));
}));
})).nThen((function() {
cb({
warning: warning.length ? warning : undefined,
channels: res,
size
});
}));
};
commands.TRIM_HISTORY = function(ctx, data, cId, cb) {
if (!ctx.store.loggedIn || !ctx.store.rpc) {
return void cb({
error: "INSUFFICIENT_PERMISSIONS"
});
}
var channels = data.channels;
if (!Array.isArray(channels)) {
return void cb({
error: "EINVAL"
});
}
var rpc = getRpc(ctx, data.teamId);
if (!rpc) {
return void cb({
error: "ENORPC"
});
}
var warning = [];
nThen((function(waitFor) {
channels.forEach((function(obj) {
rpc.trimHistory(obj, waitFor((function(err) {
if (err) {
warning.push(err);
return;
}
})));
}));
})).nThen((function() {
if (channels.length === 1 && warning.length) {
return void cb({
error: warning[0]
});
}
cb({
warning: warning.length ? warning : undefined
});
}));
};
History.init = function(cfg, waitFor, emit) {
var history = {};
if (!cfg.store) {
return;
}
var ctx = {
store: cfg.store,
Store: cfg.Store,
pinPads: cfg.pinPads,
updateMetadata: cfg.updateMetadata,
emit
};
history.execCommand = function(clientId, obj, cb) {
var cmd = obj.cmd;
var data = obj.data;
try {
commands[cmd](ctx, data, clientId, cb);
} catch (e) {
console.error(e);
}
};
return history;
};
return History;
};
if (module.exports) {
module.exports = factory(requireCommonUtil(), requireCommonHash(), requireUserObject(), requireNthen());
}
})();
})(history);
return history.exports;
}
var calendar$1 = {
exports: {}
};
var recurrence = {
exports: {}
};
var hasRequiredRecurrence;
function requireRecurrence() {
if (hasRequiredRecurrence) return recurrence.exports;
hasRequiredRecurrence = 1;
(function(module) {
(() => {
const factory = Util => {
var Rec = {};
const window = globalThis;
var debug = function() {};
var getWeekNo = Rec.getWeekNo = function(date, wkst) {
if (typeof wkst !== "number") {
wkst = 1;
}
var newYear = new Date(date.getFullYear(), 0, 1);
var day = newYear.getDay() - wkst;
day = day >= 0 ? day : day + 7;
var daynum = Math.floor((date.getTime() - newYear.getTime()) / 864e5) + 1;
var weeknum;
if (day < 4) {
weeknum = Math.floor((daynum + day - 1) / 7) + 1;
if (weeknum > 52) {
var nYear = new Date(date.getFullYear() + 1, 0, 1);
var nday = nYear.getDay() - wkst;
nday = nday >= 0 ? nday : nday + 7;
weeknum = nday < 4 ? 1 : 53;
}
} else {
weeknum = Math.floor((daynum + day - 1) / 7);
}
return weeknum;
};
var getYearDay = function(date) {
var start = new Date(date.getFullYear(), 0, 0);
var diff = date - start + (start.getTimezoneOffset() - date.getTimezoneOffset()) * 60 * 1e3;
var oneDay = 1e3 * 60 * 60 * 24;
return Math.floor(diff / oneDay);
};
var setYearDay = function(date, day) {
if (typeof day !== "number" || Math.abs(day) < 1 || Math.abs(day) > 366) {
return;
}
if (day < 0) {
var max = getYearDay(new Date(date.getFullYear(), 11, 31));
day = max + day + 1;
}
date.setMonth(0);
date.setDate(day);
return true;
};
var getEndData = function(s, e) {
if (s > e) {
return void console.error("Wrong data");
}
var days;
if (e.getFullYear() === s.getFullYear()) {
days = getYearDay(e) - getYearDay(s);
} else {
var tmp = new Date(s.getFullYear(), 11, 31);
var d1 = getYearDay(tmp) - getYearDay(s);
var de = getYearDay(e);
days = d1 + de;
while (tmp.getFullYear() + 1 < e.getFullYear()) {
tmp.setFullYear(tmp.getFullYear() + 1);
days += getYearDay(tmp);
}
}
return {
h: e.getHours(),
m: e.getMinutes(),
days
};
};
var setEndData = function(s, e, data) {
e.setTime(+s);
if (!data) {
return;
}
e.setHours(data.h);
e.setMinutes(data.m);
e.setSeconds(0);
e.setDate(s.getDate() + data.days);
};
var DAYORDER = Rec.DAYORDER = [ "SU", "MO", "TU", "WE", "TH", "FR", "SA" ];
var getDayData = function(str) {
var pos = Number(str.slice(0, -2));
var day = DAYORDER.indexOf(str.slice(-2));
return pos ? [ pos, day ] : day;
};
var goToFirstWeekDay = function(date, wkst) {
var d = date.getDay();
wkst = typeof wkst === "number" ? wkst : 1;
if (d >= wkst) {
date.setDate(date.getDate() - (d - wkst));
} else {
date.setDate(date.getDate() - (7 + d - wkst));
}
};
var getDateStr = function(date) {
return date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
};
var FREQ = {};
FREQ["daily"] = function(s, i) {
s.setDate(s.getDate() + i);
};
FREQ["weekly"] = function(s, i) {
s.setDate(s.getDate() + i * 7);
};
FREQ["monthly"] = function(s, i) {
s.setMonth(s.getMonth() + i);
};
FREQ["yearly"] = function(s, i) {
s.setFullYear(s.getFullYear() + i);
};
var EXPAND = {};
EXPAND["month"] = function(dateS, origin, b) {
var oS = new Date(origin.start);
var a = dateS.getMonth() + 1;
var toAdd = (b - a + 12) % 12;
var m = dateS.getMonth() + toAdd;
dateS.setMonth(m);
dateS.setDate(oS.getDate());
if (dateS.getMonth() !== m) {
return;
}
return true;
};
EXPAND["weekno"] = function(dateS, origin, week, rule) {
var wkst = rule && rule.wkst;
if (typeof wkst !== "number") {
wkst = 1;
}
var oS = new Date(origin.start);
var lastD = new Date(dateS.getFullYear(), 11, 31);
var lastW = getWeekNo(lastD, wkst);
var doubleOne = lastW === 1;
if (lastW === 1) {
lastW = 52;
}
var a = getWeekNo(dateS, wkst);
if (!week || week > lastW) {
return false;
}
if (week < 0) {
week = lastW + week + 1;
}
var toAdd = week - a;
var weekS = new Date(+dateS);
weekS.setDate(weekS.getDate() + toAdd * 7);
goToFirstWeekDay(weekS, wkst);
var all = "aaaaaaa".split("").map((function(o, i) {
var date = new Date(+weekS);
date.setDate(date.getDate() + i);
if (date.getFullYear() !== dateS.getFullYear()) {
return;
}
return date.toLocaleDateString() !== oS.toLocaleDateString() && date;
})).filter(Boolean);
if (week === 1 && doubleOne) {
goToFirstWeekDay(lastD, wkst);
"aaaaaaa".split("").some((function(o, i) {
var date = new Date(+lastD);
date.setDate(date.getDate() + i);
if (date.toLocaleDateString() === oS.toLocaleDateString()) {
return;
}
if (date.getFullYear() > dateS.getFullYear()) {
return true;
}
all.push(date);
}));
}
return all.length ? all : undefined;
};
EXPAND["yearday"] = function(dateS, origin, b) {
var y = dateS.getFullYear();
var state = setYearDay(dateS, b);
if (!state) {
return;
}
if (dateS.getFullYear() !== y) {
return;
}
return true;
};
EXPAND["monthday"] = function(dateS, origin, b, rule) {
if (typeof b !== "number" || Math.abs(b) < 1 || Math.abs(b) > 31) {
return false;
}
var setMonthDay = function(date, day) {
var m = date.getMonth();
if (day < 0) {
var tmp = new Date(date.getFullYear(), date.getMonth() + 1, 0);
day = tmp.getDate() + day + 1;
}
date.setDate(day);
return date.getMonth() === m;
};
if (rule.freq === "monthly") {
return setMonthDay(dateS, b);
}
var all = "aaaaaaaaaaaa".split("").map((function(o, i) {
var date = new Date(dateS.getFullYear(), i, 1);
var ok = setMonthDay(date, b);
return ok ? date : undefined;
})).filter(Boolean);
return all.length ? all : undefined;
};
EXPAND["day"] = function(dateS, origin, b, rule) {
var day = getDayData(b);
var pos;
if (Array.isArray(day)) {
pos = day[0];
day = day[1];
}
var all = [];
if (![ 0, 1, 2, 3, 4, 5, 6 ].includes(day)) {
return false;
}
var filterPos = function(m) {
if (!pos) {
return;
}
var _all = [];
"aaaaaaaaaaaa".split("").some((function(a, i) {
if (typeof m !== "undefined" && i !== m) {
return;
}
var _pos;
var tmp = all.filter((function(d) {
return d.getMonth() === i;
}));
if (pos < 0) {
_pos = tmp.length + pos;
} else {
_pos = pos - 1;
}
_all.push(tmp[_pos]);
return typeof m !== "undefined" && i === m;
}));
all = _all.filter(Boolean);
};
var tmp;
if (rule.freq === "yearly") {
tmp = new Date(+dateS);
var y = dateS.getFullYear();
while (tmp.getDay() !== day) {
tmp.setDate(tmp.getDate() + 1);
}
while (tmp.getFullYear() === y) {
all.push(new Date(+tmp));
tmp.setDate(tmp.getDate() + 7);
}
filterPos();
return all;
}
if (rule.freq === "monthly") {
tmp = new Date(+dateS);
var m = dateS.getMonth();
while (tmp.getDay() !== day) {
tmp.setDate(tmp.getDate() + 1);
}
while (tmp.getMonth() === m) {
all.push(new Date(+tmp));
tmp.setDate(tmp.getDate() + 7);
}
filterPos(m);
return all;
}
if (rule.freq === "weekly") {
while (dateS.getDay() !== day) {
dateS.setDate(dateS.getDate() + 1);
}
}
return true;
};
var LIMIT = {};
LIMIT["month"] = function(events, rule) {
return events.filter((function(s) {
return rule.includes(s.getMonth() + 1);
}));
};
LIMIT["weekno"] = function(events, weeks, rules) {
return events.filter((function(s) {
var wkst = rules && rules.wkst;
if (typeof wkst !== "number") {
wkst = 1;
}
var lastD = new Date(s.getFullYear(), 11, 31);
var lastW = getWeekNo(lastD, wkst);
if (lastW === 1) {
lastW = 52;
}
var w = getWeekNo(s, wkst);
return weeks.some((function(week) {
if (week > 0) {
return week === w;
}
return w === lastW + week + 1;
}));
}));
};
LIMIT["yearday"] = function(events, days) {
return events.filter((function(s) {
var d = getYearDay(s);
var max = getYearDay(new Date(s.getFullYear(), 11, 31));
return days.some((function(day) {
if (day > 0) {
return day === d;
}
return d === max + day + 1;
}));
}));
};
LIMIT["monthday"] = function(events, rule) {
return events.filter((function(s) {
var r = Util.clone(rule);
r = r.map((function(b) {
if (b < 0) {
var tmp = new Date(s.getFullYear(), s.getMonth() + 1, 0);
b = tmp.getDate() + b + 1;
}
return b;
}));
return r.includes(s.getDate());
}));
};
LIMIT["day"] = function(events, days, rules) {
return events.filter((function(s) {
var dayStr = s.toLocaleDateString();
var type = "yearly";
if (rules.freq === "monthly" || rules.freq === "yearly" && rules.by && rules.by.month) {
type = "monthly";
}
return days.some((function(r) {
var day = getDayData(r);
var pos;
if (Array.isArray(day)) {
pos = day[0];
day = day[1];
}
if (!pos) {
return s.getDay() === day;
}
var d = new Date(s.getFullYear(), s.getMonth(), 1);
if (type === "yearly") {
d.setMonth(0);
}
var res = EXPAND["day"](d, {}, r, {
freq: type
});
return res.some((function(date) {
return date.toLocaleDateString() === dayStr;
}));
}));
}));
};
LIMIT["setpos"] = function(events, rule) {
var init = events.slice();
var rules = Util.deduplicateString(rule.slice().map((function(n) {
if (n > 0) {
return n - 1;
}
if (n === 0) {
return;
}
return init.length + n;
})));
return events.filter((function(ev) {
var idx = init.indexOf(ev);
return rules.includes(idx);
}));
};
var BYORDER = [ "month", "weekno", "yearday", "monthday", "day" ];
var BYDAYORDER = [ "month", "monthday", "day" ];
Rec.getMonthId = function(d) {
return d.getFullYear() + "-" + d.getMonth();
};
var cache = window.CP_calendar_cache = {};
var recurringAcross = {};
Rec.resetCache = function() {
cache = window.CP_calendar_cache = {};
recurringAcross = {};
};
var iterate = function(rule, _origin, s) {
var origin = Util.clone(_origin);
var oS = new Date(origin.start);
var id = origin.id.split("|")[0];
var uid = s.toLocaleDateString();
cache[id] = cache[id] || {};
var inter = rule.interval || 1;
var freq = rule.freq;
var all = [];
var limit = function(byrule, n) {
all = LIMIT[byrule](all, n, rule);
};
var expand = function(byrule) {
return function(n) {
var _s = new Date(+s);
if (rule.freq === "yearly") {
_s.setMonth(0);
_s.setDate(1);
} else if (rule.freq === "monthly") {
_s.setDate(1);
} else if (rule.freq === "weekly") {
goToFirstWeekDay(_s, rule.wkst);
} else if (rule.freq === "daily") ;
var add = EXPAND[byrule](_s, origin, n, rule);
if (!add) {
return;
}
if (Array.isArray(add)) {
add = add.filter((function(dateS) {
return dateS.toLocaleDateString() !== oS.toLocaleDateString();
}));
Array.prototype.push.apply(all, add);
} else {
if (_s.toLocaleDateString() === oS.toLocaleDateString()) {
return;
}
all.push(_s);
}
};
};
var it = Util.once((function() {
FREQ[freq](s, inter);
}));
var addDefault = function() {
if (freq === "monthly") {
s.setDate(15);
} else if (freq === "yearly" && oS.getMonth() === 1 && oS.getDate() === 29) {
s.setDate(28);
}
it();
var _s = new Date(+s);
if (freq === "monthly" || freq === "yearly") {
_s.setDate(oS.getDate());
if (_s.getDate() !== oS.getDate()) {
return;
}
if (freq === "yearly" && _s.getMonth() !== oS.getMonth()) {
return;
}
}
all.push(_s);
};
if (Array.isArray(cache[id][uid])) {
debug("Get cache", id, uid);
if (freq === "monthly") {
s.setDate(15);
} else if (freq === "yearly" && oS.getMonth() === 1 && oS.getDate() === 29) {
s.setDate(28);
}
it();
return cache[id][uid];
}
if (rule.by && freq === "yearly") {
var order = BYORDER.slice();
var monthLimit = false;
if (rule.by.weekno || rule.by.yearday || rule.by.monthday || rule.by.day) {
order.shift();
monthLimit = true;
}
var first = true;
order.forEach((function(_order) {
var r = rule.by[_order];
if (!r) {
return;
}
if (first) {
r.forEach(expand(_order));
first = false;
} else if (_order === "day") {
if (rule.by.yearday || rule.by.monthday || rule.by.weekno) {
limit("day", rule.by.day);
} else {
rule.by.day.forEach(expand("day"));
}
} else {
limit(_order, r);
}
}));
if (rule.by.month && monthLimit) {
limit("month", rule.by.month);
}
}
if (rule.by && freq === "monthly") {
if (!rule.by.monthday && !rule.by.day) {
addDefault();
} else if (rule.by.monthday) {
rule.by.monthday.forEach(expand("monthday"));
} else if (rule.by.day) {
rule.by.day.forEach(expand("day"));
}
if (rule.by.month) {
limit("month", rule.by.month);
}
if (rule.by.day && rule.by.monthday) {
limit("day", rule.by.day);
}
}
if (rule.by && freq === "weekly") {
if (!rule.by.day) {
addDefault();
} else {
rule.by.day.forEach(expand("day"));
}
if (rule.by.month) {
limit("month", rule.by.month);
}
}
if (rule.by && freq === "daily") {
addDefault();
BYDAYORDER.forEach((function(_order) {
var r = rule.by[_order];
if (!r) {
return;
}
limit(_order, r);
}));
}
all.sort((function(a, b) {
return a - b;
}));
if (rule.by && rule.by.setpos) {
limit("setpos", rule.by.setpos);
}
if (!rule.by || !Object.keys(rule.by).length) {
addDefault();
} else {
it();
}
var done = [];
all = all.filter((function(newS) {
var start = new Date(+newS).toLocaleDateString();
if (done.includes(start)) {
return false;
}
done.push(start);
return true;
}));
debug("Set cache", id, uid);
cache[id][uid] = all;
return all;
};
var getNextRules = function(obj) {
if (!obj.recUpdate) {
return [];
}
var _allRules = {};
var _obj = obj.recUpdate.from;
Object.keys(_obj || {}).forEach((function(d) {
var u = _obj[d];
if (u.recurrenceRule) {
_allRules[d] = u.recurrenceRule;
}
}));
return Object.keys(_allRules).sort((function(a, b) {
return Number(a) - Number(b);
})).map((function(k) {
var r = Util.clone(_allRules[k]);
if (!FREQ[r.freq]) {
return;
}
if (r.interval && r.interval < 1) {
return;
}
r._start = Number(k);
return r;
})).filter(Boolean);
};
var fixTimeZone = function(evTimeZone, origin, target) {
var getOffset = function(date, tz) {
let iso = date.toLocaleString("en-CA", {
timeZone: tz,
hour12: false
}).replace(", ", "T");
iso += "." + date.getMilliseconds().toString().padStart(3, "0");
let utcDate = new Date(iso + "Z");
return -(utcDate - date);
};
var myTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
var offset = getOffset(origin, evTimeZone) - getOffset(target, evTimeZone);
var myOffset = getOffset(origin, myTimeZone) - getOffset(target, myTimeZone);
return myOffset - offset;
};
Rec.getRecurring = function(months, events) {
if (window.CP_DEV_MODE) {
debug = console.warn;
}
var toAdd = [];
months.forEach((function(monthId) {
var ms = monthId.split("-");
var _startMonth = new Date(ms[0], ms[1]);
var _endMonth = new Date(+_startMonth);
_endMonth.setMonth(_endMonth.getMonth() + 1);
_endMonth.setMilliseconds(-1);
debug("Compute month", _startMonth.toLocaleDateString());
var rec = events || [];
rec.forEach((function(obj) {
var _start = new Date(obj.start);
var _end = new Date(obj.end);
var _origin = obj;
var rule = obj.recurrenceRule;
if (!rule) {
return;
}
var nextRules = getNextRules(obj);
var nextRule = nextRules.shift();
if (_start >= _endMonth) {
return;
}
var until = rule.until;
var _nextRules = nextRules.slice();
var _nextRule = nextRule;
while (_nextRule && _nextRule._start && _nextRule._start < _startMonth) {
until = nextRule.until;
_nextRule = _nextRules.shift();
}
if (until < _startMonth) {
return;
}
var endData = getEndData(_start, _end);
if (rule.interval && rule.interval < 1) {
return;
}
if (!FREQ[rule.freq]) {
return;
}
debug("Iterate over", obj.title, obj);
debug("Use rule", rule);
var count = rule.count;
var c = 1;
var next = function(start) {
var evS = new Date(+start);
if (count && c >= count) {
return;
}
debug("Start iteration", evS.toLocaleDateString());
var _toAdd = iterate(rule, obj, evS);
debug("Iteration results", JSON.stringify(_toAdd.map((function(o) {
return new Date(o).toLocaleDateString();
}))));
if (!_toAdd.length) {
if (evS.getFullYear() < _startMonth.getFullYear() || evS < _endMonth) {
return void next(evS);
}
return;
}
var stop = false;
var newrule = false;
_toAdd.some((function(_newS) {
var _ev = Util.clone(obj);
_ev.id = _origin.id + "|" + +_newS;
var _evS = new Date(+_newS);
var _evE = new Date(+_newS);
setEndData(_evS, _evE, endData);
_ev.start = +_evS;
_ev.end = +_evE;
_ev._count = c;
if (_ev.isAllDay && _ev.startDay) {
_ev.startDay = getDateStr(_evS);
}
if (_ev.isAllDay && _ev.endDay) {
_ev.endDay = getDateStr(_evE);
}
if (nextRule && _ev.start === nextRule._start) {
newrule = true;
}
var useNewRule = function() {
if (!newrule) {
return;
}
debug("Use new rule", nextRule);
_ev._count = c;
count = nextRule.count;
c = 1;
evS = +_evS;
obj = _ev;
rule = nextRule;
nextRule = nextRules.shift();
};
if (c >= count) {
debug(_evS.toLocaleDateString(), "count");
stop = true;
return true;
}
if (_evS >= _endMonth) {
debug(_evS.toLocaleDateString(), "endMonth");
stop = true;
return true;
}
if (rule.until && _evS > rule.until) {
debug(_evS.toLocaleDateString(), "until");
stop = true;
return true;
}
if (_evS < _start) {
debug(_evS.toLocaleDateString(), "start");
return;
}
c++;
if (_evE < _startMonth) {
debug(_evS.toLocaleDateString(), "startMonth");
if (newrule) {
useNewRule();
}
return;
}
if (_evS < _endMonth && _evE >= _endMonth || _evS < _startMonth && _evE >= _startMonth) {
if (recurringAcross[_ev.id] && recurringAcross[_ev.id].includes(_ev.start)) {
return;
} else {
recurringAcross[_ev.id] = recurringAcross[_ev.id] || [];
recurringAcross[_ev.id].push(_ev.start);
}
}
if (_origin.timeZone && !_ev.isAllDay) {
var offset = fixTimeZone(_origin.timeZone, _start, _evS);
_ev.start += offset;
_ev.end += offset;
}
toAdd.push(_ev);
if (newrule) {
useNewRule();
return true;
}
}));
if (!stop) {
next(evS);
}
};
next(_start);
debug("Added this month (all events)", toAdd.map((function(ev) {
return new Date(ev.start).toLocaleDateString();
})));
}));
}));
return toAdd;
};
Rec.getAllOccurrences = function(ev) {
if (!ev.recurrenceRule) {
return [ ev.start ];
}
var r = ev.recurrenceRule;
if (!r.until && !r.count) {
return false;
}
var all = [ ev.start ];
var d = new Date(ev.start);
d.setDate(15);
var toAdd = [];
var i = 0;
var check = function() {
return r.count ? all.length < r.count : +d <= r.until;
};
while ((toAdd = Rec.getRecurring([ Rec.getMonthId(d) ], [ ev ])) && check() && i < r.count * 12) {
Array.prototype.push.apply(all, toAdd.map((function(_ev) {
return _ev.start;
})));
d.setMonth(d.getMonth() + 1);
i++;
}
return all;
};
Rec.diffDate = function(oldTime, newTime) {
var n = new Date(newTime);
var o = new Date(oldTime);
var d = 0;
var mult = n < o ? -1 : 1;
while (n.toLocaleDateString() !== o.toLocaleDateString() || mult >= 1e4) {
n.setDate(n.getDate() - mult);
d++;
}
d = mult * d;
n = new Date(newTime);
var h = n.getHours() - o.getHours();
var m = n.getMinutes() - o.getMinutes();
return {
d,
h,
m
};
};
var sortUpdate = function(obj) {
return Object.keys(obj).sort((function(d1, d2) {
return Number(d1) - Number(d2);
}));
};
Rec.applyUpdates = function(events) {
events.forEach((function(ev) {
ev.raw = {
start: ev.start,
end: ev.end
};
if (!ev.recUpdate) {
return;
}
var from = ev.recUpdate.from || {};
var one = ev.recUpdate.one || {};
var s = ev.start;
var nextRules = getNextRules(ev).filter((function(r) {
return r._start > s;
}));
var nextRule = nextRules.shift();
var applyDiff = function(obj, k) {
var diff = obj[k];
var d = new Date(ev.raw[k]);
d.setDate(d.getDate() + diff.d);
d.setHours(d.getHours() + diff.h);
d.setMinutes(d.getMinutes() + diff.m);
ev[k] = +d;
};
sortUpdate(from).forEach((function(d) {
if (s < Number(d)) {
return;
}
Object.keys(from[d]).forEach((function(k) {
if (k === "start" || k === "end") {
return void applyDiff(from[d], k);
}
if (k === "recurrenceRule" && !from[d][k]) {
return;
}
ev[k] = from[d][k];
}));
}));
Object.keys(one[s] || {}).forEach((function(k) {
if (k === "start" || k === "end") {
return void applyDiff(one[s], k);
}
if (k === "recurrenceRule" && !one[s][k]) {
return;
}
ev[k] = one[s][k];
}));
if (ev.deleted) {
Object.keys(ev).forEach((function(k) {
delete ev[k];
}));
}
if (nextRule && ev.recurrenceRule) {
ev.recurrenceRule._next = nextRule._start - 1;
}
if (ev.reminders) {
ev.raw.reminders = ev.reminders;
}
}));
return events;
};
return Rec;
};
if (module.exports) {
module.exports = factory(requireCommonUtil());
}
})();
})(recurrence);
return recurrence.exports;
}
var flatpickr$1 = {
exports: {}
};
/* flatpickr v4.6.9,, @license MIT */ var flatpickr = flatpickr$1.exports;
var hasRequiredFlatpickr;
function requireFlatpickr() {
if (hasRequiredFlatpickr) return flatpickr$1.exports;
hasRequiredFlatpickr = 1;
(function(module, exports) {
!function(e, t) {
module.exports = t();
}(flatpickr, (function() {
var e = function() {
return (e = Object.assign || function(e) {
for (var t, n = 1, a = arguments.length; n < a; n++) for (var i in t = arguments[n]) Object.prototype.hasOwnProperty.call(t, i) && (e[i] = t[i]);
return e;
}).apply(this, arguments);
};
function t() {
for (var e = 0, t = 0, n = arguments.length; t < n; t++) e += arguments[t].length;
var a = Array(e), i = 0;
for (t = 0; t < n; t++) for (var o = arguments[t], r = 0, l = o.length; r < l; r++,
i++) a[i] = o[r];
return a;
}
var n = [ "onChange", "onClose", "onDayCreate", "onDestroy", "onKeyDown", "onMonthChange", "onOpen", "onParseConfig", "onReady", "onValueUpdate", "onYearChange", "onPreCalendarPosition" ], a = {
_disable: [],
allowInput: !1,
allowInvalidPreload: !1,
altFormat: "F j, Y",
altInput: !1,
altInputClass: "form-control input",
animate: "object" == typeof window && -1 === window.navigator.userAgent.indexOf("MSIE"),
ariaDateFormat: "F j, Y",
autoFillDefaultTime: !0,
clickOpens: !0,
closeOnSelect: !0,
conjunction: ", ",
dateFormat: "Y-m-d",
defaultHour: 12,
defaultMinute: 0,
defaultSeconds: 0,
disable: [],
disableMobile: !1,
enableSeconds: !1,
enableTime: !1,
errorHandler: function(e) {
return "undefined" != typeof console && console.warn(e);
},
getWeek: function(e) {
var t = new Date(e.getTime());
t.setHours(0, 0, 0, 0), t.setDate(t.getDate() + 3 - (t.getDay() + 6) % 7);
var n = new Date(t.getFullYear(), 0, 4);
return 1 + Math.round(((t.getTime() - n.getTime()) / 864e5 - 3 + (n.getDay() + 6) % 7) / 7);
},
hourIncrement: 1,
ignoredFocusElements: [],
inline: !1,
locale: "default",
minuteIncrement: 5,
mode: "single",
monthSelectorType: "dropdown",
nextArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M13.207 8.472l-7.854 7.854-0.707-0.707 7.146-7.146-7.146-7.148 0.707-0.707 7.854 7.854z' /></svg>",
noCalendar: !1,
now: new Date,
onChange: [],
onClose: [],
onDayCreate: [],
onDestroy: [],
onKeyDown: [],
onMonthChange: [],
onOpen: [],
onParseConfig: [],
onReady: [],
onValueUpdate: [],
onYearChange: [],
onPreCalendarPosition: [],
plugins: [],
position: "auto",
positionElement: void 0,
prevArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M5.207 8.471l7.146 7.147-0.707 0.707-7.853-7.854 7.854-7.853 0.707 0.707-7.147 7.146z' /></svg>",
shorthandCurrentMonth: !1,
showMonths: 1,
static: !1,
time_24hr: !1,
weekNumbers: !1,
wrap: !1
}, i = {
weekdays: {
shorthand: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ],
longhand: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ]
},
months: {
shorthand: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ],
longhand: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]
},
daysInMonth: [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ],
firstDayOfWeek: 0,
ordinal: function(e) {
var t = e % 100;
if (t > 3 && t < 21) return "th";
switch (t % 10) {
case 1:
return "st";
case 2:
return "nd";
case 3:
return "rd";
default:
return "th";
}
},
rangeSeparator: " to ",
weekAbbreviation: "Wk",
scrollTitle: "Scroll to increment",
toggleTitle: "Click to toggle",
amPM: [ "AM", "PM" ],
yearAriaLabel: "Year",
monthAriaLabel: "Month",
hourAriaLabel: "Hour",
minuteAriaLabel: "Minute",
time_24hr: !1
}, o = function(e, t) {
return void 0 === t && (t = 2), ("000" + e).slice(-1 * t);
}, r = function(e) {
return !0 === e ? 1 : 0;
};
function l(e, t) {
var n;
return function() {
var a = this;
clearTimeout(n), n = setTimeout((function() {
return e.apply(a, arguments);
}), t);
};
}
var c = function(e) {
return e instanceof Array ? e : [ e ];
};
function d(e, t, n) {
if (!0 === n) return e.classList.add(t);
e.classList.remove(t);
}
function s(e, t, n) {
var a = window.document.createElement(e);
return t = t || "", n = n || "", a.className = t, void 0 !== n && (a.textContent = n),
a;
}
function u(e) {
for (;e.firstChild; ) e.removeChild(e.firstChild);
}
function f(e, t) {
return t(e) ? e : e.parentNode ? f(e.parentNode, t) : void 0;
}
function m(e, t) {
var n = s("div", "numInputWrapper"), a = s("input", "numInput " + e), i = s("span", "arrowUp"), o = s("span", "arrowDown");
if (-1 === navigator.userAgent.indexOf("MSIE 9.0") ? a.type = "number" : (a.type = "text",
a.pattern = "\\d*"), void 0 !== t) for (var r in t) a.setAttribute(r, t[r]);
return n.appendChild(a), n.appendChild(i), n.appendChild(o), n;
}
function g(e) {
try {
return "function" == typeof e.composedPath ? e.composedPath()[0] : e.target;
} catch (t) {
return e.target;
}
}
var p = function() {}, h = function(e, t, n) {
return n.months[t ? "shorthand" : "longhand"][e];
}, v = {
D: p,
F: function(e, t, n) {
e.setMonth(n.months.longhand.indexOf(t));
},
G: function(e, t) {
e.setHours(parseFloat(t));
},
H: function(e, t) {
e.setHours(parseFloat(t));
},
J: function(e, t) {
e.setDate(parseFloat(t));
},
K: function(e, t, n) {
e.setHours(e.getHours() % 12 + 12 * r(new RegExp(n.amPM[1], "i").test(t)));
},
M: function(e, t, n) {
e.setMonth(n.months.shorthand.indexOf(t));
},
S: function(e, t) {
e.setSeconds(parseFloat(t));
},
U: function(e, t) {
return new Date(1e3 * parseFloat(t));
},
W: function(e, t, n) {
var a = parseInt(t), i = new Date(e.getFullYear(), 0, 2 + 7 * (a - 1), 0, 0, 0, 0);
return i.setDate(i.getDate() - i.getDay() + n.firstDayOfWeek), i;
},
Y: function(e, t) {
e.setFullYear(parseFloat(t));
},
Z: function(e, t) {
return new Date(t);
},
d: function(e, t) {
e.setDate(parseFloat(t));
},
h: function(e, t) {
e.setHours(parseFloat(t));
},
i: function(e, t) {
e.setMinutes(parseFloat(t));
},
j: function(e, t) {
e.setDate(parseFloat(t));
},
l: p,
m: function(e, t) {
e.setMonth(parseFloat(t) - 1);
},
n: function(e, t) {
e.setMonth(parseFloat(t) - 1);
},
s: function(e, t) {
e.setSeconds(parseFloat(t));
},
u: function(e, t) {
return new Date(parseFloat(t));
},
w: p,
y: function(e, t) {
e.setFullYear(2e3 + parseFloat(t));
}
}, D = {
D: "(\\w+)",
F: "(\\w+)",
G: "(\\d\\d|\\d)",
H: "(\\d\\d|\\d)",
J: "(\\d\\d|\\d)\\w+",
K: "",
M: "(\\w+)",
S: "(\\d\\d|\\d)",
U: "(.+)",
W: "(\\d\\d|\\d)",
Y: "(\\d{4})",
Z: "(.+)",
d: "(\\d\\d|\\d)",
h: "(\\d\\d|\\d)",
i: "(\\d\\d|\\d)",
j: "(\\d\\d|\\d)",
l: "(\\w+)",
m: "(\\d\\d|\\d)",
n: "(\\d\\d|\\d)",
s: "(\\d\\d|\\d)",
u: "(.+)",
w: "(\\d\\d|\\d)",
y: "(\\d{2})"
}, w = {
Z: function(e) {
return e.toISOString();
},
D: function(e, t, n) {
return t.weekdays.shorthand[w.w(e, t, n)];
},
F: function(e, t, n) {
return h(w.n(e, t, n) - 1, !1, t);
},
G: function(e, t, n) {
return o(w.h(e, t, n));
},
H: function(e) {
return o(e.getHours());
},
J: function(e, t) {
return void 0 !== t.ordinal ? e.getDate() + t.ordinal(e.getDate()) : e.getDate();
},
K: function(e, t) {
return t.amPM[r(e.getHours() > 11)];
},
M: function(e, t) {
return h(e.getMonth(), !0, t);
},
S: function(e) {
return o(e.getSeconds());
},
U: function(e) {
return e.getTime() / 1e3;
},
W: function(e, t, n) {
return n.getWeek(e);
},
Y: function(e) {
return o(e.getFullYear(), 4);
},
d: function(e) {
return o(e.getDate());
},
h: function(e) {
return e.getHours() % 12 ? e.getHours() % 12 : 12;
},
i: function(e) {
return o(e.getMinutes());
},
j: function(e) {
return e.getDate();
},
l: function(e, t) {
return t.weekdays.longhand[e.getDay()];
},
m: function(e) {
return o(e.getMonth() + 1);
},
n: function(e) {
return e.getMonth() + 1;
},
s: function(e) {
return e.getSeconds();
},
u: function(e) {
return e.getTime();
},
w: function(e) {
return e.getDay();
},
y: function(e) {
return String(e.getFullYear()).substring(2);
}
}, b = function(e) {
var t = e.config, n = void 0 === t ? a : t, o = e.l10n, r = void 0 === o ? i : o, l = e.isMobile, c = void 0 !== l && l;
return function(e, t, a) {
var i = a || r;
return void 0 === n.formatDate || c ? t.split("").map((function(t, a, o) {
return w[t] && "\\" !== o[a - 1] ? w[t](e, i, n) : "\\" !== t ? t : "";
})).join("") : n.formatDate(e, t, i);
};
}, C = function(e) {
var t = e.config, n = void 0 === t ? a : t, o = e.l10n, r = void 0 === o ? i : o;
return function(e, t, i, o) {
if (0 === e || e) {
var l, c = o || r, d = e;
if (e instanceof Date) l = new Date(e.getTime()); else if ("string" != typeof e && void 0 !== e.toFixed) l = new Date(e); else if ("string" == typeof e) {
var s = t || (n || a).dateFormat, u = String(e).trim();
if ("today" === u) l = new Date, i = !0; else if (/Z$/.test(u) || /GMT$/.test(u)) l = new Date(e); else if (n && n.parseDate) l = n.parseDate(e, s); else {
l = n && n.noCalendar ? new Date((new Date).setHours(0, 0, 0, 0)) : new Date((new Date).getFullYear(), 0, 1, 0, 0, 0, 0);
for (var f = void 0, m = [], g = 0, p = 0, h = ""; g < s.length; g++) {
var w = s[g], b = "\\" === w, C = "\\" === s[g - 1] || b;
if (D[w] && !C) {
h += D[w];
var M = new RegExp(h).exec(e);
M && (f = !0) && m["Y" !== w ? "push" : "unshift"]({
fn: v[w],
val: M[++p]
});
} else b || (h += ".");
m.forEach((function(e) {
var t = e.fn, n = e.val;
return l = t(l, n, c) || l;
}));
}
l = f ? l : void 0;
}
}
if (l instanceof Date && !isNaN(l.getTime())) return !0 === i && l.setHours(0, 0, 0, 0),
l;
n.errorHandler(new Error("Invalid date provided: " + d));
}
};
};
function M(e, t, n) {
return void 0 === n && (n = !0), !1 !== n ? new Date(e.getTime()).setHours(0, 0, 0, 0) - new Date(t.getTime()).setHours(0, 0, 0, 0) : e.getTime() - t.getTime();
}
var y = 864e5;
function x(e) {
var t = e.defaultHour, n = e.defaultMinute, a = e.defaultSeconds;
if (void 0 !== e.minDate) {
var i = e.minDate.getHours(), o = e.minDate.getMinutes(), r = e.minDate.getSeconds();
t < i && (t = i), t === i && n < o && (n = o), t === i && n === o && a < r && (a = e.minDate.getSeconds());
}
if (void 0 !== e.maxDate) {
var l = e.maxDate.getHours(), c = e.maxDate.getMinutes();
(t = Math.min(t, l)) === l && (n = Math.min(c, n)), t === l && n === c && (a = e.maxDate.getSeconds());
}
return {
hours: t,
minutes: n,
seconds: a
};
}
"function" != typeof Object.assign && (Object.assign = function(e) {
for (var t = [], n = 1; n < arguments.length; n++) t[n - 1] = arguments[n];
if (!e) throw TypeError("Cannot convert undefined or null to object");
for (var a = function(t) {
t && Object.keys(t).forEach((function(n) {
return e[n] = t[n];
}));
}, i = 0, o = t; i < o.length; i++) {
var r = o[i];
a(r);
}
return e;
});
function E(p, v) {
var w = {
config: e(e({}, a), T.defaultConfig),
l10n: i
};
function E(e) {
return e.bind(w);
}
function k() {
var e = w.config;
!1 === e.weekNumbers && 1 === e.showMonths || !0 !== e.noCalendar && window.requestAnimationFrame((function() {
if (void 0 !== w.calendarContainer && (w.calendarContainer.style.visibility = "hidden",
w.calendarContainer.style.display = "block"), void 0 !== w.daysContainer) {
var t = (w.days.offsetWidth + 1) * e.showMonths;
w.daysContainer.style.width = t + "px", w.calendarContainer.style.width = t + (void 0 !== w.weekWrapper ? w.weekWrapper.offsetWidth : 0) + "px",
w.calendarContainer.style.removeProperty("visibility"), w.calendarContainer.style.removeProperty("display");
}
}));
}
function I(e) {
if (0 === w.selectedDates.length) {
var t = void 0 === w.config.minDate || M(new Date, w.config.minDate) >= 0 ? new Date : new Date(w.config.minDate.getTime()), n = x(w.config);
t.setHours(n.hours, n.minutes, n.seconds, t.getMilliseconds()), w.selectedDates = [ t ],
w.latestSelectedDateObj = t;
}
void 0 !== e && "blur" !== e.type && function(e) {
e.preventDefault();
var t = "keydown" === e.type, n = g(e), a = n;
void 0 !== w.amPM && n === w.amPM && (w.amPM.textContent = w.l10n.amPM[r(w.amPM.textContent === w.l10n.amPM[0])]);
var i = parseFloat(a.getAttribute("min")), l = parseFloat(a.getAttribute("max")), c = parseFloat(a.getAttribute("step")), d = parseInt(a.value, 10), s = e.delta || (t ? 38 === e.which ? 1 : -1 : 0), u = d + c * s;
if (void 0 !== a.value && 2 === a.value.length) {
var f = a === w.hourElement, m = a === w.minuteElement;
u < i ? (u = l + u + r(!f) + (r(f) && r(!w.amPM)), m && j(void 0, -1, w.hourElement)) : u > l && (u = a === w.hourElement ? u - l - r(!w.amPM) : i,
m && j(void 0, 1, w.hourElement)), w.amPM && f && (1 === c ? u + d === 23 : Math.abs(u - d) > c) && (w.amPM.textContent = w.l10n.amPM[r(w.amPM.textContent === w.l10n.amPM[0])]),
a.value = o(u);
}
}(e);
var a = w._input.value;
S(), be(), w._input.value !== a && w._debouncedChange();
}
function S() {
if (void 0 !== w.hourElement && void 0 !== w.minuteElement) {
var e, t, n = (parseInt(w.hourElement.value.slice(-2), 10) || 0) % 24, a = (parseInt(w.minuteElement.value, 10) || 0) % 60, i = void 0 !== w.secondElement ? (parseInt(w.secondElement.value, 10) || 0) % 60 : 0;
void 0 !== w.amPM && (e = n, t = w.amPM.textContent, n = e % 12 + 12 * r(t === w.l10n.amPM[1]));
var o = void 0 !== w.config.minTime || w.config.minDate && w.minDateHasTime && w.latestSelectedDateObj && 0 === M(w.latestSelectedDateObj, w.config.minDate, !0);
if (void 0 !== w.config.maxTime || w.config.maxDate && w.maxDateHasTime && w.latestSelectedDateObj && 0 === M(w.latestSelectedDateObj, w.config.maxDate, !0)) {
var l = void 0 !== w.config.maxTime ? w.config.maxTime : w.config.maxDate;
(n = Math.min(n, l.getHours())) === l.getHours() && (a = Math.min(a, l.getMinutes())),
a === l.getMinutes() && (i = Math.min(i, l.getSeconds()));
}
if (o) {
var c = void 0 !== w.config.minTime ? w.config.minTime : w.config.minDate;
(n = Math.max(n, c.getHours())) === c.getHours() && a < c.getMinutes() && (a = c.getMinutes()),
a === c.getMinutes() && (i = Math.max(i, c.getSeconds()));
}
O(n, a, i);
}
}
function _(e) {
var t = e || w.latestSelectedDateObj;
t && O(t.getHours(), t.getMinutes(), t.getSeconds());
}
function O(e, t, n) {
void 0 !== w.latestSelectedDateObj && w.latestSelectedDateObj.setHours(e % 24, t, n || 0, 0),
w.hourElement && w.minuteElement && !w.isMobile && (w.hourElement.value = o(w.config.time_24hr ? e : (12 + e) % 12 + 12 * r(e % 12 == 0)),
w.minuteElement.value = o(t), void 0 !== w.amPM && (w.amPM.textContent = w.l10n.amPM[r(e >= 12)]),
void 0 !== w.secondElement && (w.secondElement.value = o(n)));
}
function F(e) {
var t = g(e), n = parseInt(t.value) + (e.delta || 0);
(n / 1e3 > 1 || "Enter" === e.key && !/[^\d]/.test(n.toString())) && Q(n);
}
function A(e, t, n, a) {
return t instanceof Array ? t.forEach((function(t) {
return A(e, t, n, a);
})) : e instanceof Array ? e.forEach((function(e) {
return A(e, t, n, a);
})) : (e.addEventListener(t, n, a), void w._handlers.push({
remove: function() {
return e.removeEventListener(t, n);
}
}));
}
function N() {
pe("onChange");
}
function P(e, t) {
var n = void 0 !== e ? w.parseDate(e) : w.latestSelectedDateObj || (w.config.minDate && w.config.minDate > w.now ? w.config.minDate : w.config.maxDate && w.config.maxDate < w.now ? w.config.maxDate : w.now), a = w.currentYear, i = w.currentMonth;
try {
void 0 !== n && (w.currentYear = n.getFullYear(), w.currentMonth = n.getMonth());
} catch (e) {
e.message = "Invalid date supplied: " + n, w.config.errorHandler(e);
}
t && w.currentYear !== a && (pe("onYearChange"), K()), !t || w.currentYear === a && w.currentMonth === i || pe("onMonthChange"),
w.redraw();
}
function Y(e) {
var t = g(e);
~t.className.indexOf("arrow") && j(e, t.classList.contains("arrowUp") ? 1 : -1);
}
function j(e, t, n) {
var a = e && g(e), i = n || a && a.parentNode && a.parentNode.firstChild, o = he("increment");
o.delta = t, i && i.dispatchEvent(o);
}
function H(e, t, n, a) {
var i = X(t, !0), o = s("span", "flatpickr-day " + e, t.getDate().toString());
return o.dateObj = t, o.$i = a, o.setAttribute("aria-label", w.formatDate(t, w.config.ariaDateFormat)),
-1 === e.indexOf("hidden") && 0 === M(t, w.now) && (w.todayDateElem = o, o.classList.add("today"),
o.setAttribute("aria-current", "date")), i ? (o.tabIndex = -1, ve(t) && (o.classList.add("selected"),
w.selectedDateElem = o, "range" === w.config.mode && (d(o, "startRange", w.selectedDates[0] && 0 === M(t, w.selectedDates[0], !0)),
d(o, "endRange", w.selectedDates[1] && 0 === M(t, w.selectedDates[1], !0)), "nextMonthDay" === e && o.classList.add("inRange")))) : o.classList.add("flatpickr-disabled"),
"range" === w.config.mode && function(e) {
return !("range" !== w.config.mode || w.selectedDates.length < 2) && (M(e, w.selectedDates[0]) >= 0 && M(e, w.selectedDates[1]) <= 0);
}(t) && !ve(t) && o.classList.add("inRange"), w.weekNumbers && 1 === w.config.showMonths && "prevMonthDay" !== e && n % 7 == 1 && w.weekNumbers.insertAdjacentHTML("beforeend", "<span class='flatpickr-day'>" + w.config.getWeek(t) + "</span>"),
pe("onDayCreate", o), o;
}
function L(e) {
e.focus(), "range" === w.config.mode && ae(e);
}
function W(e) {
for (var t = e > 0 ? 0 : w.config.showMonths - 1, n = e > 0 ? w.config.showMonths : -1, a = t; a != n; a += e) for (var i = w.daysContainer.children[a], o = e > 0 ? 0 : i.children.length - 1, r = e > 0 ? i.children.length : -1, l = o; l != r; l += e) {
var c = i.children[l];
if (-1 === c.className.indexOf("hidden") && X(c.dateObj)) return c;
}
}
function R(e, t) {
var n = ee(document.activeElement || document.body), a = void 0 !== e ? e : n ? document.activeElement : void 0 !== w.selectedDateElem && ee(w.selectedDateElem) ? w.selectedDateElem : void 0 !== w.todayDateElem && ee(w.todayDateElem) ? w.todayDateElem : W(t > 0 ? 1 : -1);
void 0 === a ? w._input.focus() : n ? function(e, t) {
for (var n = -1 === e.className.indexOf("Month") ? e.dateObj.getMonth() : w.currentMonth, a = t > 0 ? w.config.showMonths : -1, i = t > 0 ? 1 : -1, o = n - w.currentMonth; o != a; o += i) for (var r = w.daysContainer.children[o], l = n - w.currentMonth === o ? e.$i + t : t < 0 ? r.children.length - 1 : 0, c = r.children.length, d = l; d >= 0 && d < c && d != (t > 0 ? c : -1); d += i) {
var s = r.children[d];
if (-1 === s.className.indexOf("hidden") && X(s.dateObj) && Math.abs(e.$i - d) >= Math.abs(t)) return L(s);
}
w.changeMonth(i), R(W(i), 0);
}(a, t) : L(a);
}
function B(e, t) {
for (var n = (new Date(e, t, 1).getDay() - w.l10n.firstDayOfWeek + 7) % 7, a = w.utils.getDaysInMonth((t - 1 + 12) % 12, e), i = w.utils.getDaysInMonth(t, e), o = window.document.createDocumentFragment(), r = w.config.showMonths > 1, l = r ? "prevMonthDay hidden" : "prevMonthDay", c = r ? "nextMonthDay hidden" : "nextMonthDay", d = a + 1 - n, u = 0; d <= a; d++,
u++) o.appendChild(H(l, new Date(e, t - 1, d), d, u));
for (d = 1; d <= i; d++, u++) o.appendChild(H("", new Date(e, t, d), d, u));
for (var f = i + 1; f <= 42 - n && (1 === w.config.showMonths || u % 7 != 0); f++,
u++) o.appendChild(H(c, new Date(e, t + 1, f % i), f, u));
var m = s("div", "dayContainer");
return m.appendChild(o), m;
}
function J() {
if (void 0 !== w.daysContainer) {
u(w.daysContainer), w.weekNumbers && u(w.weekNumbers);
for (var e = document.createDocumentFragment(), t = 0; t < w.config.showMonths; t++) {
var n = new Date(w.currentYear, w.currentMonth, 1);
n.setMonth(w.currentMonth + t), e.appendChild(B(n.getFullYear(), n.getMonth()));
}
w.daysContainer.appendChild(e), w.days = w.daysContainer.firstChild, "range" === w.config.mode && 1 === w.selectedDates.length && ae();
}
}
function K() {
if (!(w.config.showMonths > 1 || "dropdown" !== w.config.monthSelectorType)) {
var e = function(e) {
return !(void 0 !== w.config.minDate && w.currentYear === w.config.minDate.getFullYear() && e < w.config.minDate.getMonth()) && !(void 0 !== w.config.maxDate && w.currentYear === w.config.maxDate.getFullYear() && e > w.config.maxDate.getMonth());
};
w.monthsDropdownContainer.tabIndex = -1, w.monthsDropdownContainer.innerHTML = "";
for (var t = 0; t < 12; t++) if (e(t)) {
var n = s("option", "flatpickr-monthDropdown-month");
n.value = new Date(w.currentYear, t).getMonth().toString(), n.textContent = h(t, w.config.shorthandCurrentMonth, w.l10n),
n.tabIndex = -1, w.currentMonth === t && (n.selected = !0), w.monthsDropdownContainer.appendChild(n);
}
}
}
function U() {
var e, t = s("div", "flatpickr-month"), n = window.document.createDocumentFragment();
w.config.showMonths > 1 || "static" === w.config.monthSelectorType ? e = s("span", "cur-month") : (w.monthsDropdownContainer = s("select", "flatpickr-monthDropdown-months"),
w.monthsDropdownContainer.setAttribute("aria-label", w.l10n.monthAriaLabel), A(w.monthsDropdownContainer, "change", (function(e) {
var t = g(e), n = parseInt(t.value, 10);
w.changeMonth(n - w.currentMonth), pe("onMonthChange");
})), K(), e = w.monthsDropdownContainer);
var a = m("cur-year", {
tabindex: "-1"
}), i = a.getElementsByTagName("input")[0];
i.setAttribute("aria-label", w.l10n.yearAriaLabel), w.config.minDate && i.setAttribute("min", w.config.minDate.getFullYear().toString()),
w.config.maxDate && (i.setAttribute("max", w.config.maxDate.getFullYear().toString()),
i.disabled = !!w.config.minDate && w.config.minDate.getFullYear() === w.config.maxDate.getFullYear());
var o = s("div", "flatpickr-current-month");
return o.appendChild(e), o.appendChild(a), n.appendChild(o), t.appendChild(n), {
container: t,
yearElement: i,
monthElement: e
};
}
function q() {
u(w.monthNav), w.monthNav.appendChild(w.prevMonthNav), w.config.showMonths && (w.yearElements = [],
w.monthElements = []);
for (var e = w.config.showMonths; e--; ) {
var t = U();
w.yearElements.push(t.yearElement), w.monthElements.push(t.monthElement), w.monthNav.appendChild(t.container);
}
w.monthNav.appendChild(w.nextMonthNav);
}
function $() {
w.weekdayContainer ? u(w.weekdayContainer) : w.weekdayContainer = s("div", "flatpickr-weekdays");
for (var e = w.config.showMonths; e--; ) {
var t = s("div", "flatpickr-weekdaycontainer");
w.weekdayContainer.appendChild(t);
}
return z(), w.weekdayContainer;
}
function z() {
if (w.weekdayContainer) {
var e = w.l10n.firstDayOfWeek, n = t(w.l10n.weekdays.shorthand);
e > 0 && e < n.length && (n = t(n.splice(e, n.length), n.splice(0, e)));
for (var a = w.config.showMonths; a--; ) w.weekdayContainer.children[a].innerHTML = "\n <span class='flatpickr-weekday'>\n " + n.join("</span><span class='flatpickr-weekday'>") + "\n </span>\n ";
}
}
function G(e, t) {
void 0 === t && (t = !0);
var n = t ? e : e - w.currentMonth;
n < 0 && !0 === w._hidePrevMonthArrow || n > 0 && !0 === w._hideNextMonthArrow || (w.currentMonth += n,
(w.currentMonth < 0 || w.currentMonth > 11) && (w.currentYear += w.currentMonth > 11 ? 1 : -1,
w.currentMonth = (w.currentMonth + 12) % 12, pe("onYearChange"), K()), J(), pe("onMonthChange"),
De());
}
function V(e) {
return !(!w.config.appendTo || !w.config.appendTo.contains(e)) || w.calendarContainer.contains(e);
}
function Z(e) {
if (w.isOpen && !w.config.inline) {
var t = g(e), n = V(t), a = t === w.input || t === w.altInput || w.element.contains(t) || e.path && e.path.indexOf && (~e.path.indexOf(w.input) || ~e.path.indexOf(w.altInput)), i = "blur" === e.type ? a && e.relatedTarget && !V(e.relatedTarget) : !a && !n && !V(e.relatedTarget), o = !w.config.ignoredFocusElements.some((function(e) {
return e.contains(t);
}));
i && o && (void 0 !== w.timeContainer && void 0 !== w.minuteElement && void 0 !== w.hourElement && "" !== w.input.value && void 0 !== w.input.value && I(),
w.close(), w.config && "range" === w.config.mode && 1 === w.selectedDates.length && (w.clear(!1),
w.redraw()));
}
}
function Q(e) {
if (!(!e || w.config.minDate && e < w.config.minDate.getFullYear() || w.config.maxDate && e > w.config.maxDate.getFullYear())) {
var t = e, n = w.currentYear !== t;
w.currentYear = t || w.currentYear, w.config.maxDate && w.currentYear === w.config.maxDate.getFullYear() ? w.currentMonth = Math.min(w.config.maxDate.getMonth(), w.currentMonth) : w.config.minDate && w.currentYear === w.config.minDate.getFullYear() && (w.currentMonth = Math.max(w.config.minDate.getMonth(), w.currentMonth)),
n && (w.redraw(), pe("onYearChange"), K());
}
}
function X(e, t) {
var n;
void 0 === t && (t = !0);
var a = w.parseDate(e, void 0, t);
if (w.config.minDate && a && M(a, w.config.minDate, void 0 !== t ? t : !w.minDateHasTime) < 0 || w.config.maxDate && a && M(a, w.config.maxDate, void 0 !== t ? t : !w.maxDateHasTime) > 0) return !1;
if (!w.config.enable && 0 === w.config.disable.length) return !0;
if (void 0 === a) return !1;
for (var i = !!w.config.enable, o = null !== (n = w.config.enable) && void 0 !== n ? n : w.config.disable, r = 0, l = void 0; r < o.length; r++) {
if ("function" == typeof (l = o[r]) && l(a)) return i;
if (l instanceof Date && void 0 !== a && l.getTime() === a.getTime()) return i;
if ("string" == typeof l) {
var c = w.parseDate(l, void 0, !0);
return c && c.getTime() === a.getTime() ? i : !i;
}
if ("object" == typeof l && void 0 !== a && l.from && l.to && a.getTime() >= l.from.getTime() && a.getTime() <= l.to.getTime()) return i;
}
return !i;
}
function ee(e) {
return void 0 !== w.daysContainer && (-1 === e.className.indexOf("hidden") && -1 === e.className.indexOf("flatpickr-disabled") && w.daysContainer.contains(e));
}
function te(e) {
!(e.target === w._input) || !(w.selectedDates.length > 0 || w._input.value.length > 0) || e.relatedTarget && V(e.relatedTarget) || w.setDate(w._input.value, !0, e.target === w.altInput ? w.config.altFormat : w.config.dateFormat);
}
function ne(e) {
var t = g(e), n = w.config.wrap ? p.contains(t) : t === w._input, a = w.config.allowInput, i = w.isOpen && (!a || !n), o = w.config.inline && n && !a;
if (13 === e.keyCode && n) {
if (a) return w.setDate(w._input.value, !0, t === w.altInput ? w.config.altFormat : w.config.dateFormat),
t.blur();
w.open();
} else if (V(t) || i || o) {
var r = !!w.timeContainer && w.timeContainer.contains(t);
switch (e.keyCode) {
case 13:
r ? (e.preventDefault(), I(), se()) : ue(e);
break;
case 27:
e.preventDefault(), se();
break;
case 8:
case 46:
n && !w.config.allowInput && (e.preventDefault(), w.clear());
break;
case 37:
case 39:
if (r || n) w.hourElement && w.hourElement.focus(); else if (e.preventDefault(),
void 0 !== w.daysContainer && (!1 === a || document.activeElement && ee(document.activeElement))) {
var l = 39 === e.keyCode ? 1 : -1;
e.ctrlKey ? (e.stopPropagation(), G(l), R(W(1), 0)) : R(void 0, l);
}
break;
case 38:
case 40:
e.preventDefault();
var c = 40 === e.keyCode ? 1 : -1;
w.daysContainer && void 0 !== t.$i || t === w.input || t === w.altInput ? e.ctrlKey ? (e.stopPropagation(),
Q(w.currentYear - c), R(W(1), 0)) : r || R(void 0, 7 * c) : t === w.currentYearElement ? Q(w.currentYear - c) : w.config.enableTime && (!r && w.hourElement && w.hourElement.focus(),
I(e), w._debouncedChange());
break;
case 9:
if (r) {
var d = [ w.hourElement, w.minuteElement, w.secondElement, w.amPM ].concat(w.pluginElements).filter((function(e) {
return e;
})), s = d.indexOf(t);
if (-1 !== s) {
var u = d[s + (e.shiftKey ? -1 : 1)];
e.preventDefault(), (u || w._input).focus();
}
} else !w.config.noCalendar && w.daysContainer && w.daysContainer.contains(t) && e.shiftKey && (e.preventDefault(),
w._input.focus());
}
}
if (void 0 !== w.amPM && t === w.amPM) switch (e.key) {
case w.l10n.amPM[0].charAt(0):
case w.l10n.amPM[0].charAt(0).toLowerCase():
w.amPM.textContent = w.l10n.amPM[0], S(), be();
break;
case w.l10n.amPM[1].charAt(0):
case w.l10n.amPM[1].charAt(0).toLowerCase():
w.amPM.textContent = w.l10n.amPM[1], S(), be();
}
(n || V(t)) && pe("onKeyDown", e);
}
function ae(e) {
if (1 === w.selectedDates.length && (!e || e.classList.contains("flatpickr-day") && !e.classList.contains("flatpickr-disabled"))) {
for (var t = e ? e.dateObj.getTime() : w.days.firstElementChild.dateObj.getTime(), n = w.parseDate(w.selectedDates[0], void 0, !0).getTime(), a = Math.min(t, w.selectedDates[0].getTime()), i = Math.max(t, w.selectedDates[0].getTime()), o = !1, r = 0, l = 0, c = a; c < i; c += y) X(new Date(c), !0) || (o = o || c > a && c < i,
c < n && (!r || c > r) ? r = c : c > n && (!l || c < l) && (l = c));
for (var d = 0; d < w.config.showMonths; d++) for (var s = w.daysContainer.children[d], u = function(a, i) {
var c, d, u, f = s.children[a], m = f.dateObj.getTime(), g = r > 0 && m < r || l > 0 && m > l;
return g ? (f.classList.add("notAllowed"), [ "inRange", "startRange", "endRange" ].forEach((function(e) {
f.classList.remove(e);
})), "continue") : o && !g ? "continue" : ([ "startRange", "inRange", "endRange", "notAllowed" ].forEach((function(e) {
f.classList.remove(e);
})), void (void 0 !== e && (e.classList.add(t <= w.selectedDates[0].getTime() ? "startRange" : "endRange"),
n < t && m === n ? f.classList.add("startRange") : n > t && m === n && f.classList.add("endRange"),
m >= r && (0 === l || m <= l) && (d = n, u = t, (c = m) > Math.min(d, u) && c < Math.max(d, u)) && f.classList.add("inRange"))));
}, f = 0, m = s.children.length; f < m; f++) u(f);
}
}
function ie() {
!w.isOpen || w.config.static || w.config.inline || ce();
}
function oe(e) {
return function(t) {
var n = w.config["_" + e + "Date"] = w.parseDate(t, w.config.dateFormat), a = w.config["_" + ("min" === e ? "max" : "min") + "Date"];
void 0 !== n && (w["min" === e ? "minDateHasTime" : "maxDateHasTime"] = n.getHours() > 0 || n.getMinutes() > 0 || n.getSeconds() > 0),
w.selectedDates && (w.selectedDates = w.selectedDates.filter((function(e) {
return X(e);
})), w.selectedDates.length || "min" !== e || _(n), be()), w.daysContainer && (de(),
void 0 !== n ? w.currentYearElement[e] = n.getFullYear().toString() : w.currentYearElement.removeAttribute(e),
w.currentYearElement.disabled = !!a && void 0 !== n && a.getFullYear() === n.getFullYear());
};
}
function re() {
return w.config.wrap ? p.querySelector("[data-input]") : p;
}
function le() {
"object" != typeof w.config.locale && void 0 === T.l10ns[w.config.locale] && w.config.errorHandler(new Error("flatpickr: invalid locale " + w.config.locale)),
w.l10n = e(e({}, T.l10ns.default), "object" == typeof w.config.locale ? w.config.locale : "default" !== w.config.locale ? T.l10ns[w.config.locale] : void 0),
D.K = "(" + w.l10n.amPM[0] + "|" + w.l10n.amPM[1] + "|" + w.l10n.amPM[0].toLowerCase() + "|" + w.l10n.amPM[1].toLowerCase() + ")",
void 0 === e(e({}, v), JSON.parse(JSON.stringify(p.dataset || {}))).time_24hr && void 0 === T.defaultConfig.time_24hr && (w.config.time_24hr = w.l10n.time_24hr),
w.formatDate = b(w), w.parseDate = C({
config: w.config,
l10n: w.l10n
});
}
function ce(e) {
if ("function" != typeof w.config.position) {
if (void 0 !== w.calendarContainer) {
pe("onPreCalendarPosition");
var t = e || w._positionElement, n = Array.prototype.reduce.call(w.calendarContainer.children, (function(e, t) {
return e + t.offsetHeight;
}), 0), a = w.calendarContainer.offsetWidth, i = w.config.position.split(" "), o = i[0], r = i.length > 1 ? i[1] : null, l = t.getBoundingClientRect(), c = window.innerHeight - l.bottom, s = "above" === o || "below" !== o && c < n && l.top > n, u = window.pageYOffset + l.top + (s ? -n - 2 : t.offsetHeight + 2);
if (d(w.calendarContainer, "arrowTop", !s), d(w.calendarContainer, "arrowBottom", s),
!w.config.inline) {
var f = window.pageXOffset + l.left, m = !1, g = !1;
"center" === r ? (f -= (a - l.width) / 2, m = !0) : "right" === r && (f -= a - l.width,
g = !0), d(w.calendarContainer, "arrowLeft", !m && !g), d(w.calendarContainer, "arrowCenter", m),
d(w.calendarContainer, "arrowRight", g);
var p = window.document.body.offsetWidth - (window.pageXOffset + l.right), h = f + a > window.document.body.offsetWidth, v = p + a > window.document.body.offsetWidth;
if (d(w.calendarContainer, "rightMost", h), !w.config.static) if (w.calendarContainer.style.top = u + "px",
h) if (v) {
var D = function() {
for (var e = null, t = 0; t < document.styleSheets.length; t++) {
var n = document.styleSheets[t];
try {
n.cssRules;
} catch (e) {
continue;
}
e = n;
break;
}
return null != e ? e : (a = document.createElement("style"), document.head.appendChild(a),
a.sheet);
var a;
}();
if (void 0 === D) return;
var b = window.document.body.offsetWidth, C = Math.max(0, b / 2 - a / 2), M = D.cssRules.length, y = "{left:" + l.left + "px;right:auto;}";
d(w.calendarContainer, "rightMost", !1), d(w.calendarContainer, "centerMost", !0),
D.insertRule(".flatpickr-calendar.centerMost:before,.flatpickr-calendar.centerMost:after" + y, M),
w.calendarContainer.style.left = C + "px", w.calendarContainer.style.right = "auto";
} else w.calendarContainer.style.left = "auto", w.calendarContainer.style.right = p + "px"; else w.calendarContainer.style.left = f + "px",
w.calendarContainer.style.right = "auto";
}
}
} else w.config.position(w, e);
}
function de() {
w.config.noCalendar || w.isMobile || (K(), De(), J());
}
function se() {
w._input.focus(), -1 !== window.navigator.userAgent.indexOf("MSIE") || void 0 !== navigator.msMaxTouchPoints ? setTimeout(w.close, 0) : w.close();
}
function ue(e) {
e.preventDefault(), e.stopPropagation();
var t = f(g(e), (function(e) {
return e.classList && e.classList.contains("flatpickr-day") && !e.classList.contains("flatpickr-disabled") && !e.classList.contains("notAllowed");
}));
if (void 0 !== t) {
var n = t, a = w.latestSelectedDateObj = new Date(n.dateObj.getTime()), i = (a.getMonth() < w.currentMonth || a.getMonth() > w.currentMonth + w.config.showMonths - 1) && "range" !== w.config.mode;
if (w.selectedDateElem = n, "single" === w.config.mode) w.selectedDates = [ a ]; else if ("multiple" === w.config.mode) {
var o = ve(a);
o ? w.selectedDates.splice(parseInt(o), 1) : w.selectedDates.push(a);
} else "range" === w.config.mode && (2 === w.selectedDates.length && w.clear(!1, !1),
w.latestSelectedDateObj = a, w.selectedDates.push(a), 0 !== M(a, w.selectedDates[0], !0) && w.selectedDates.sort((function(e, t) {
return e.getTime() - t.getTime();
})));
if (S(), i) {
var r = w.currentYear !== a.getFullYear();
w.currentYear = a.getFullYear(), w.currentMonth = a.getMonth(), r && (pe("onYearChange"),
K()), pe("onMonthChange");
}
if (De(), J(), be(), i || "range" === w.config.mode || 1 !== w.config.showMonths ? void 0 !== w.selectedDateElem && void 0 === w.hourElement && w.selectedDateElem && w.selectedDateElem.focus() : L(n),
void 0 !== w.hourElement && void 0 !== w.hourElement && w.hourElement.focus(), w.config.closeOnSelect) {
var l = "single" === w.config.mode && !w.config.enableTime, c = "range" === w.config.mode && 2 === w.selectedDates.length && !w.config.enableTime;
(l || c) && se();
}
N();
}
}
w.parseDate = C({
config: w.config,
l10n: w.l10n
}), w._handlers = [], w.pluginElements = [], w.loadedPlugins = [], w._bind = A,
w._setHoursFromDate = _, w._positionCalendar = ce, w.changeMonth = G, w.changeYear = Q,
w.clear = function(e, t) {
void 0 === e && (e = !0);
void 0 === t && (t = !0);
w.input.value = "", void 0 !== w.altInput && (w.altInput.value = "");
void 0 !== w.mobileInput && (w.mobileInput.value = "");
w.selectedDates = [], w.latestSelectedDateObj = void 0, !0 === t && (w.currentYear = w._initialDate.getFullYear(),
w.currentMonth = w._initialDate.getMonth());
if (!0 === w.config.enableTime) {
var n = x(w.config), a = n.hours, i = n.minutes, o = n.seconds;
O(a, i, o);
}
w.redraw(), e && pe("onChange");
}, w.close = function() {
w.isOpen = !1, w.isMobile || (void 0 !== w.calendarContainer && w.calendarContainer.classList.remove("open"),
void 0 !== w._input && w._input.classList.remove("active"));
pe("onClose");
}, w._createElement = s, w.destroy = function() {
void 0 !== w.config && pe("onDestroy");
for (var e = w._handlers.length; e--; ) w._handlers[e].remove();
if (w._handlers = [], w.mobileInput) w.mobileInput.parentNode && w.mobileInput.parentNode.removeChild(w.mobileInput),
w.mobileInput = void 0; else if (w.calendarContainer && w.calendarContainer.parentNode) if (w.config.static && w.calendarContainer.parentNode) {
var t = w.calendarContainer.parentNode;
if (t.lastChild && t.removeChild(t.lastChild), t.parentNode) {
for (;t.firstChild; ) t.parentNode.insertBefore(t.firstChild, t);
t.parentNode.removeChild(t);
}
} else w.calendarContainer.parentNode.removeChild(w.calendarContainer);
w.altInput && (w.input.type = "text", w.altInput.parentNode && w.altInput.parentNode.removeChild(w.altInput),
delete w.altInput);
w.input && (w.input.type = w.input._type, w.input.classList.remove("flatpickr-input"),
w.input.removeAttribute("readonly"));
[ "_showTimeInput", "latestSelectedDateObj", "_hideNextMonthArrow", "_hidePrevMonthArrow", "__hideNextMonthArrow", "__hidePrevMonthArrow", "isMobile", "isOpen", "selectedDateElem", "minDateHasTime", "maxDateHasTime", "days", "daysContainer", "_input", "_positionElement", "innerContainer", "rContainer", "monthNav", "todayDateElem", "calendarContainer", "weekdayContainer", "prevMonthNav", "nextMonthNav", "monthsDropdownContainer", "currentMonthElement", "currentYearElement", "navigationCurrentMonth", "selectedDateElem", "config" ].forEach((function(e) {
try {
delete w[e];
} catch (e) {}
}));
}, w.isEnabled = X, w.jumpToDate = P, w.open = function(e, t) {
void 0 === t && (t = w._positionElement);
if (!0 === w.isMobile) {
if (e) {
e.preventDefault();
var n = g(e);
n && n.blur();
}
return void 0 !== w.mobileInput && (w.mobileInput.focus(), w.mobileInput.click()),
void pe("onOpen");
}
if (w._input.disabled || w.config.inline) return;
var a = w.isOpen;
w.isOpen = !0, a || (w.calendarContainer.classList.add("open"), w._input.classList.add("active"),
pe("onOpen"), ce(t));
!0 === w.config.enableTime && !0 === w.config.noCalendar && (!1 !== w.config.allowInput || void 0 !== e && w.timeContainer.contains(e.relatedTarget) || setTimeout((function() {
return w.hourElement.select();
}), 50));
}, w.redraw = de, w.set = function(e, t) {
if (null !== e && "object" == typeof e) for (var a in Object.assign(w.config, e),
e) void 0 !== fe[a] && fe[a].forEach((function(e) {
return e();
})); else w.config[e] = t, void 0 !== fe[e] ? fe[e].forEach((function(e) {
return e();
})) : n.indexOf(e) > -1 && (w.config[e] = c(t));
w.redraw(), be(!0);
}, w.setDate = function(e, t, n) {
void 0 === t && (t = !1);
void 0 === n && (n = w.config.dateFormat);
if (0 !== e && !e || e instanceof Array && 0 === e.length) return w.clear(t);
me(e, n), w.latestSelectedDateObj = w.selectedDates[w.selectedDates.length - 1],
w.redraw(), P(void 0, t), _(), 0 === w.selectedDates.length && w.clear(!1);
be(t), t && pe("onChange");
}, w.toggle = function(e) {
if (!0 === w.isOpen) return w.close();
w.open(e);
};
var fe = {
locale: [ le, z ],
showMonths: [ q, k, $ ],
minDate: [ P ],
maxDate: [ P ],
clickOpens: [ function() {
!0 === w.config.clickOpens ? (A(w._input, "focus", w.open), A(w._input, "click", w.open)) : (w._input.removeEventListener("focus", w.open),
w._input.removeEventListener("click", w.open));
} ]
};
function me(e, t) {
var n = [];
if (e instanceof Array) n = e.map((function(e) {
return w.parseDate(e, t);
})); else if (e instanceof Date || "number" == typeof e) n = [ w.parseDate(e, t) ]; else if ("string" == typeof e) switch (w.config.mode) {
case "single":
case "time":
n = [ w.parseDate(e, t) ];
break;
case "multiple":
n = e.split(w.config.conjunction).map((function(e) {
return w.parseDate(e, t);
}));
break;
case "range":
n = e.split(w.l10n.rangeSeparator).map((function(e) {
return w.parseDate(e, t);
}));
} else w.config.errorHandler(new Error("Invalid date supplied: " + JSON.stringify(e)));
w.selectedDates = w.config.allowInvalidPreload ? n : n.filter((function(e) {
return e instanceof Date && X(e, !1);
})), "range" === w.config.mode && w.selectedDates.sort((function(e, t) {
return e.getTime() - t.getTime();
}));
}
function ge(e) {
return e.slice().map((function(e) {
return "string" == typeof e || "number" == typeof e || e instanceof Date ? w.parseDate(e, void 0, !0) : e && "object" == typeof e && e.from && e.to ? {
from: w.parseDate(e.from, void 0),
to: w.parseDate(e.to, void 0)
} : e;
})).filter((function(e) {
return e;
}));
}
function pe(e, t) {
if (void 0 !== w.config) {
var n = w.config[e];
if (void 0 !== n && n.length > 0) for (var a = 0; n[a] && a < n.length; a++) n[a](w.selectedDates, w.input.value, w, t);
"onChange" === e && (w.input.dispatchEvent(he("change")), w.input.dispatchEvent(he("input")));
}
}
function he(e) {
var t = document.createEvent("Event");
return t.initEvent(e, !0, !0), t;
}
function ve(e) {
for (var t = 0; t < w.selectedDates.length; t++) if (0 === M(w.selectedDates[t], e)) return "" + t;
return !1;
}
function De() {
w.config.noCalendar || w.isMobile || !w.monthNav || (w.yearElements.forEach((function(e, t) {
var n = new Date(w.currentYear, w.currentMonth, 1);
n.setMonth(w.currentMonth + t), w.config.showMonths > 1 || "static" === w.config.monthSelectorType ? w.monthElements[t].textContent = h(n.getMonth(), w.config.shorthandCurrentMonth, w.l10n) + " " : w.monthsDropdownContainer.value = n.getMonth().toString(),
e.value = n.getFullYear().toString();
})), w._hidePrevMonthArrow = void 0 !== w.config.minDate && (w.currentYear === w.config.minDate.getFullYear() ? w.currentMonth <= w.config.minDate.getMonth() : w.currentYear < w.config.minDate.getFullYear()),
w._hideNextMonthArrow = void 0 !== w.config.maxDate && (w.currentYear === w.config.maxDate.getFullYear() ? w.currentMonth + 1 > w.config.maxDate.getMonth() : w.currentYear > w.config.maxDate.getFullYear()));
}
function we(e) {
return w.selectedDates.map((function(t) {
return w.formatDate(t, e);
})).filter((function(e, t, n) {
return "range" !== w.config.mode || w.config.enableTime || n.indexOf(e) === t;
})).join("range" !== w.config.mode ? w.config.conjunction : w.l10n.rangeSeparator);
}
function be(e) {
void 0 === e && (e = !0), void 0 !== w.mobileInput && w.mobileFormatStr && (w.mobileInput.value = void 0 !== w.latestSelectedDateObj ? w.formatDate(w.latestSelectedDateObj, w.mobileFormatStr) : ""),
w.input.value = we(w.config.dateFormat), void 0 !== w.altInput && (w.altInput.value = we(w.config.altFormat)),
!1 !== e && pe("onValueUpdate");
}
function Ce(e) {
var t = g(e), n = w.prevMonthNav.contains(t), a = w.nextMonthNav.contains(t);
n || a ? G(n ? -1 : 1) : w.yearElements.indexOf(t) >= 0 ? t.select() : t.classList.contains("arrowUp") ? w.changeYear(w.currentYear + 1) : t.classList.contains("arrowDown") && w.changeYear(w.currentYear - 1);
}
return function() {
w.element = w.input = p, w.isOpen = !1, function() {
var t = [ "wrap", "weekNumbers", "allowInput", "allowInvalidPreload", "clickOpens", "time_24hr", "enableTime", "noCalendar", "altInput", "shorthandCurrentMonth", "inline", "static", "enableSeconds", "disableMobile" ], i = e(e({}, JSON.parse(JSON.stringify(p.dataset || {}))), v), o = {};
w.config.parseDate = i.parseDate, w.config.formatDate = i.formatDate, Object.defineProperty(w.config, "enable", {
get: function() {
return w.config._enable;
},
set: function(e) {
w.config._enable = ge(e);
}
}), Object.defineProperty(w.config, "disable", {
get: function() {
return w.config._disable;
},
set: function(e) {
w.config._disable = ge(e);
}
});
var r = "time" === i.mode;
if (!i.dateFormat && (i.enableTime || r)) {
var l = T.defaultConfig.dateFormat || a.dateFormat;
o.dateFormat = i.noCalendar || r ? "H:i" + (i.enableSeconds ? ":S" : "") : l + " H:i" + (i.enableSeconds ? ":S" : "");
}
if (i.altInput && (i.enableTime || r) && !i.altFormat) {
var d = T.defaultConfig.altFormat || a.altFormat;
o.altFormat = i.noCalendar || r ? "h:i" + (i.enableSeconds ? ":S K" : " K") : d + " h:i" + (i.enableSeconds ? ":S" : "") + " K";
}
Object.defineProperty(w.config, "minDate", {
get: function() {
return w.config._minDate;
},
set: oe("min")
}), Object.defineProperty(w.config, "maxDate", {
get: function() {
return w.config._maxDate;
},
set: oe("max")
});
var s = function(e) {
return function(t) {
w.config["min" === e ? "_minTime" : "_maxTime"] = w.parseDate(t, "H:i:S");
};
};
Object.defineProperty(w.config, "minTime", {
get: function() {
return w.config._minTime;
},
set: s("min")
}), Object.defineProperty(w.config, "maxTime", {
get: function() {
return w.config._maxTime;
},
set: s("max")
}), "time" === i.mode && (w.config.noCalendar = !0, w.config.enableTime = !0);
Object.assign(w.config, o, i);
for (var u = 0; u < t.length; u++) w.config[t[u]] = !0 === w.config[t[u]] || "true" === w.config[t[u]];
n.filter((function(e) {
return void 0 !== w.config[e];
})).forEach((function(e) {
w.config[e] = c(w.config[e] || []).map(E);
})), w.isMobile = !w.config.disableMobile && !w.config.inline && "single" === w.config.mode && !w.config.disable.length && !w.config.enable && !w.config.weekNumbers && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
for (u = 0; u < w.config.plugins.length; u++) {
var f = w.config.plugins[u](w) || {};
for (var m in f) n.indexOf(m) > -1 ? w.config[m] = c(f[m]).map(E).concat(w.config[m]) : void 0 === i[m] && (w.config[m] = f[m]);
}
i.altInputClass || (w.config.altInputClass = re().className + " " + w.config.altInputClass);
pe("onParseConfig");
}(), le(), function() {
if (w.input = re(), !w.input) return void w.config.errorHandler(new Error("Invalid input element specified"));
w.input._type = w.input.type, w.input.type = "text", w.input.classList.add("flatpickr-input"),
w._input = w.input, w.config.altInput && (w.altInput = s(w.input.nodeName, w.config.altInputClass),
w._input = w.altInput, w.altInput.placeholder = w.input.placeholder, w.altInput.disabled = w.input.disabled,
w.altInput.required = w.input.required, w.altInput.tabIndex = w.input.tabIndex,
w.altInput.type = "text", w.input.setAttribute("type", "hidden"), !w.config.static && w.input.parentNode && w.input.parentNode.insertBefore(w.altInput, w.input.nextSibling));
w.config.allowInput || w._input.setAttribute("readonly", "readonly");
w._positionElement = w.config.positionElement || w._input;
}(), function() {
w.selectedDates = [], w.now = w.parseDate(w.config.now) || new Date;
var e = w.config.defaultDate || ("INPUT" !== w.input.nodeName && "TEXTAREA" !== w.input.nodeName || !w.input.placeholder || w.input.value !== w.input.placeholder ? w.input.value : null);
e && me(e, w.config.dateFormat);
w._initialDate = w.selectedDates.length > 0 ? w.selectedDates[0] : w.config.minDate && w.config.minDate.getTime() > w.now.getTime() ? w.config.minDate : w.config.maxDate && w.config.maxDate.getTime() < w.now.getTime() ? w.config.maxDate : w.now,
w.currentYear = w._initialDate.getFullYear(), w.currentMonth = w._initialDate.getMonth(),
w.selectedDates.length > 0 && (w.latestSelectedDateObj = w.selectedDates[0]);
void 0 !== w.config.minTime && (w.config.minTime = w.parseDate(w.config.minTime, "H:i"));
void 0 !== w.config.maxTime && (w.config.maxTime = w.parseDate(w.config.maxTime, "H:i"));
w.minDateHasTime = !!w.config.minDate && (w.config.minDate.getHours() > 0 || w.config.minDate.getMinutes() > 0 || w.config.minDate.getSeconds() > 0),
w.maxDateHasTime = !!w.config.maxDate && (w.config.maxDate.getHours() > 0 || w.config.maxDate.getMinutes() > 0 || w.config.maxDate.getSeconds() > 0);
}(), w.utils = {
getDaysInMonth: function(e, t) {
return void 0 === e && (e = w.currentMonth), void 0 === t && (t = w.currentYear),
1 === e && (t % 4 == 0 && t % 100 != 0 || t % 400 == 0) ? 29 : w.l10n.daysInMonth[e];
}
}, w.isMobile || function() {
var e = window.document.createDocumentFragment();
if (w.calendarContainer = s("div", "flatpickr-calendar"), w.calendarContainer.tabIndex = -1,
!w.config.noCalendar) {
if (e.appendChild((w.monthNav = s("div", "flatpickr-months"), w.yearElements = [],
w.monthElements = [], w.prevMonthNav = s("span", "flatpickr-prev-month"), w.prevMonthNav.innerHTML = w.config.prevArrow,
w.nextMonthNav = s("span", "flatpickr-next-month"), w.nextMonthNav.innerHTML = w.config.nextArrow,
q(), Object.defineProperty(w, "_hidePrevMonthArrow", {
get: function() {
return w.__hidePrevMonthArrow;
},
set: function(e) {
w.__hidePrevMonthArrow !== e && (d(w.prevMonthNav, "flatpickr-disabled", e), w.__hidePrevMonthArrow = e);
}
}), Object.defineProperty(w, "_hideNextMonthArrow", {
get: function() {
return w.__hideNextMonthArrow;
},
set: function(e) {
w.__hideNextMonthArrow !== e && (d(w.nextMonthNav, "flatpickr-disabled", e), w.__hideNextMonthArrow = e);
}
}), w.currentYearElement = w.yearElements[0], De(), w.monthNav)), w.innerContainer = s("div", "flatpickr-innerContainer"),
w.config.weekNumbers) {
var t = function() {
w.calendarContainer.classList.add("hasWeeks");
var e = s("div", "flatpickr-weekwrapper");
e.appendChild(s("span", "flatpickr-weekday", w.l10n.weekAbbreviation));
var t = s("div", "flatpickr-weeks");
return e.appendChild(t), {
weekWrapper: e,
weekNumbers: t
};
}(), n = t.weekWrapper, a = t.weekNumbers;
w.innerContainer.appendChild(n), w.weekNumbers = a, w.weekWrapper = n;
}
w.rContainer = s("div", "flatpickr-rContainer"), w.rContainer.appendChild($()),
w.daysContainer || (w.daysContainer = s("div", "flatpickr-days"), w.daysContainer.tabIndex = -1),
J(), w.rContainer.appendChild(w.daysContainer), w.innerContainer.appendChild(w.rContainer),
e.appendChild(w.innerContainer);
}
w.config.enableTime && e.appendChild(function() {
w.calendarContainer.classList.add("hasTime"), w.config.noCalendar && w.calendarContainer.classList.add("noCalendar");
var e = x(w.config);
w.timeContainer = s("div", "flatpickr-time"), w.timeContainer.tabIndex = -1;
var t = s("span", "flatpickr-time-separator", ":"), n = m("flatpickr-hour", {
"aria-label": w.l10n.hourAriaLabel
});
w.hourElement = n.getElementsByTagName("input")[0];
var a = m("flatpickr-minute", {
"aria-label": w.l10n.minuteAriaLabel
});
w.minuteElement = a.getElementsByTagName("input")[0], w.hourElement.tabIndex = w.minuteElement.tabIndex = -1,
w.hourElement.value = o(w.latestSelectedDateObj ? w.latestSelectedDateObj.getHours() : w.config.time_24hr ? e.hours : function(e) {
switch (e % 24) {
case 0:
case 12:
return 12;
default:
return e % 12;
}
}(e.hours)), w.minuteElement.value = o(w.latestSelectedDateObj ? w.latestSelectedDateObj.getMinutes() : e.minutes),
w.hourElement.setAttribute("step", w.config.hourIncrement.toString()), w.minuteElement.setAttribute("step", w.config.minuteIncrement.toString()),
w.hourElement.setAttribute("min", w.config.time_24hr ? "0" : "1"), w.hourElement.setAttribute("max", w.config.time_24hr ? "23" : "12"),
w.hourElement.setAttribute("maxlength", "2"), w.minuteElement.setAttribute("min", "0"),
w.minuteElement.setAttribute("max", "59"), w.minuteElement.setAttribute("maxlength", "2"),
w.timeContainer.appendChild(n), w.timeContainer.appendChild(t), w.timeContainer.appendChild(a),
w.config.time_24hr && w.timeContainer.classList.add("time24hr");
if (w.config.enableSeconds) {
w.timeContainer.classList.add("hasSeconds");
var i = m("flatpickr-second");
w.secondElement = i.getElementsByTagName("input")[0], w.secondElement.value = o(w.latestSelectedDateObj ? w.latestSelectedDateObj.getSeconds() : e.seconds),
w.secondElement.setAttribute("step", w.minuteElement.getAttribute("step")), w.secondElement.setAttribute("min", "0"),
w.secondElement.setAttribute("max", "59"), w.secondElement.setAttribute("maxlength", "2"),
w.timeContainer.appendChild(s("span", "flatpickr-time-separator", ":")), w.timeContainer.appendChild(i);
}
w.config.time_24hr || (w.amPM = s("span", "flatpickr-am-pm", w.l10n.amPM[r((w.latestSelectedDateObj ? w.hourElement.value : w.config.defaultHour) > 11)]),
w.amPM.title = w.l10n.toggleTitle, w.amPM.tabIndex = -1, w.timeContainer.appendChild(w.amPM));
return w.timeContainer;
}());
d(w.calendarContainer, "rangeMode", "range" === w.config.mode), d(w.calendarContainer, "animate", !0 === w.config.animate),
d(w.calendarContainer, "multiMonth", w.config.showMonths > 1), w.calendarContainer.appendChild(e);
var i = void 0 !== w.config.appendTo && void 0 !== w.config.appendTo.nodeType;
if ((w.config.inline || w.config.static) && (w.calendarContainer.classList.add(w.config.inline ? "inline" : "static"),
w.config.inline && (!i && w.element.parentNode ? w.element.parentNode.insertBefore(w.calendarContainer, w._input.nextSibling) : void 0 !== w.config.appendTo && w.config.appendTo.appendChild(w.calendarContainer)),
w.config.static)) {
var l = s("div", "flatpickr-wrapper");
w.element.parentNode && w.element.parentNode.insertBefore(l, w.element), l.appendChild(w.element),
w.altInput && l.appendChild(w.altInput), l.appendChild(w.calendarContainer);
}
w.config.static || w.config.inline || (void 0 !== w.config.appendTo ? w.config.appendTo : window.document.body).appendChild(w.calendarContainer);
}(), function() {
w.config.wrap && [ "open", "close", "toggle", "clear" ].forEach((function(e) {
Array.prototype.forEach.call(w.element.querySelectorAll("[data-" + e + "]"), (function(t) {
return A(t, "click", w[e]);
}));
}));
if (w.isMobile) return void function() {
var e = w.config.enableTime ? w.config.noCalendar ? "time" : "datetime-local" : "date";
w.mobileInput = s("input", w.input.className + " flatpickr-mobile"), w.mobileInput.tabIndex = 1,
w.mobileInput.type = e, w.mobileInput.disabled = w.input.disabled, w.mobileInput.required = w.input.required,
w.mobileInput.placeholder = w.input.placeholder, w.mobileFormatStr = "datetime-local" === e ? "Y-m-d\\TH:i:S" : "date" === e ? "Y-m-d" : "H:i:S",
w.selectedDates.length > 0 && (w.mobileInput.defaultValue = w.mobileInput.value = w.formatDate(w.selectedDates[0], w.mobileFormatStr));
w.config.minDate && (w.mobileInput.min = w.formatDate(w.config.minDate, "Y-m-d"));
w.config.maxDate && (w.mobileInput.max = w.formatDate(w.config.maxDate, "Y-m-d"));
w.input.getAttribute("step") && (w.mobileInput.step = String(w.input.getAttribute("step")));
w.input.type = "hidden", void 0 !== w.altInput && (w.altInput.type = "hidden");
try {
w.input.parentNode && w.input.parentNode.insertBefore(w.mobileInput, w.input.nextSibling);
} catch (e) {}
A(w.mobileInput, "change", (function(e) {
w.setDate(g(e).value, !1, w.mobileFormatStr), pe("onChange"), pe("onClose");
}));
}();
var e = l(ie, 50);
w._debouncedChange = l(N, 300), w.daysContainer && !/iPhone|iPad|iPod/i.test(navigator.userAgent) && A(w.daysContainer, "mouseover", (function(e) {
"range" === w.config.mode && ae(g(e));
}));
A(window.document.body, "keydown", ne), w.config.inline || w.config.static || A(window, "resize", e);
void 0 !== window.ontouchstart ? A(window.document, "touchstart", Z) : A(window.document, "mousedown", Z);
A(window.document, "focus", Z, {
capture: !0
}), !0 === w.config.clickOpens && (A(w._input, "focus", w.open), A(w._input, "click", w.open));
void 0 !== w.daysContainer && (A(w.monthNav, "click", Ce), A(w.monthNav, [ "keyup", "increment" ], F),
A(w.daysContainer, "click", ue));
if (void 0 !== w.timeContainer && void 0 !== w.minuteElement && void 0 !== w.hourElement) {
var t = function(e) {
return g(e).select();
};
A(w.timeContainer, [ "increment" ], I), A(w.timeContainer, "blur", I, {
capture: !0
}), A(w.timeContainer, "click", Y), A([ w.hourElement, w.minuteElement ], [ "focus", "click" ], t),
void 0 !== w.secondElement && A(w.secondElement, "focus", (function() {
return w.secondElement && w.secondElement.select();
})), void 0 !== w.amPM && A(w.amPM, "click", (function(e) {
I(e), N();
}));
}
w.config.allowInput && A(w._input, "blur", te);
}(), (w.selectedDates.length || w.config.noCalendar) && (w.config.enableTime && _(w.config.noCalendar ? w.latestSelectedDateObj : void 0),
be(!1)), k();
var t = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
!w.isMobile && t && ce(), pe("onReady");
}(), w;
}
function k(e, t) {
for (var n = Array.prototype.slice.call(e).filter((function(e) {
return e instanceof HTMLElement;
})), a = [], i = 0; i < n.length; i++) {
var o = n[i];
try {
if (null !== o.getAttribute("data-fp-omit")) continue;
void 0 !== o._flatpickr && (o._flatpickr.destroy(), o._flatpickr = void 0), o._flatpickr = E(o, t || {}),
a.push(o._flatpickr);
} catch (e) {
console.error(e);
}
}
return 1 === a.length ? a[0] : a;
}
"undefined" != typeof HTMLElement && "undefined" != typeof HTMLCollection && "undefined" != typeof NodeList && (HTMLCollection.prototype.flatpickr = NodeList.prototype.flatpickr = function(e) {
return k(this, e);
}, HTMLElement.prototype.flatpickr = function(e) {
return k([ this ], e);
});
var T = function(e, t) {
return "string" == typeof e ? k(window.document.querySelectorAll(e), t) : e instanceof Node ? k([ e ], t) : k(e, t);
};
return T.defaultConfig = {}, T.l10ns = {
en: e({}, i),
default: e({}, i)
}, T.localize = function(t) {
T.l10ns.default = e(e({}, T.l10ns.default), t);
}, T.setDefaults = function(t) {
T.defaultConfig = e(e({}, T.defaultConfig), t);
}, T.parseDate = C({}), T.formatDate = b({}), T.compareDates = M, "undefined" != typeof jQuery && void 0 !== jQuery.fn && (jQuery.fn.flatpickr = function(e) {
return k(this, e);
}), Date.prototype.fp_incr = function(e) {
return new Date(this.getFullYear(), this.getMonth(), this.getDate() + ("string" == typeof e ? parseInt(e, 10) : e));
}, "undefined" != typeof window && (window.flatpickr = T), T;
}));
})(flatpickr$1);
return flatpickr$1.exports;
}
var hasRequiredCalendar;
function requireCalendar() {
if (hasRequiredCalendar) return calendar$1.exports;
hasRequiredCalendar = 1;
(function(module) {
(() => {
const factory = (Util, Hash, Constants, Realtime, Cache, Rec, nThen, Listmap, FP, Crypto, ChainPad) => {
var Calendar = {};
Calendar.setCustomize = () => {};
var getStore = function(ctx, id) {
if (!id || id === 1) {
return ctx.store;
}
var m = ctx.store.modules && ctx.store.modules.team;
if (!m) {
return;
}
return m.getTeam(id);
};
var makeCalendar = function() {
var hash = Hash.createRandomHash("calendar");
var secret = Hash.getSecrets("calendar", hash);
var roHash = Hash.getViewHashFromKeys(secret);
var href = Hash.hashToHref(hash, "calendar");
var roHref = Hash.hashToHref(roHash, "calendar");
return {
href,
roHref,
channel: secret.channel
};
};
var initializeCalendars = function(ctx, cb) {
var proxy = ctx.store.proxy;
proxy.calendars = proxy.calendars || {};
setTimeout(cb);
};
var sendUpdate = function(ctx, c) {
ctx.emit("UPDATE", {
teams: c.stores,
roTeams: c.roStores,
id: c.channel,
loading: !c.ready && !c.cacheready,
readOnly: c.readOnly || !c.ready && c.cacheready || c.offline,
offline: c.offline,
deleted: !c.stores.length,
restricted: c.restricted,
owned: ctx.Store.isOwned(c.owners),
content: Util.clone(c.proxy),
hashes: c.hashes
}, ctx.clients);
};
var clearReminders = function(ctx, id) {
var calendar = ctx.calendars[id];
if (!calendar || !calendar.reminders) {
return;
}
Object.keys(calendar.reminders).forEach((function(uid) {
if (!Array.isArray(calendar.reminders[uid])) {
return;
}
calendar.reminders[uid].forEach((function(to) {
clearTimeout(to);
}));
}));
};
var closeCalendar = function(ctx, id) {
var ctxCal = ctx.calendars[id];
if (!ctxCal) {
return;
}
if (!ctxCal.stores.length) {
ctxCal.lm.stop();
clearReminders(ctx, id);
delete ctx.calendars[id];
}
};
var updateLocalCalendars = function(ctx, c, data) {
c.stores.forEach((function(id) {
var s = getStore(ctx, id);
if (!s || !s.proxy) {
return;
}
if (!s.rpc) {
return;
}
if (!s.proxy.calendars) {
return;
}
var cal = s.proxy.calendars[c.channel];
if (!cal) {
return;
}
if (cal.color !== data.color) {
cal.color = data.color;
}
if (cal.title !== data.title) {
cal.title = data.title;
}
}));
};
var getRecurring = function(ev) {
var mid = new Date;
var start = new Date(mid.getFullYear(), mid.getMonth() - 1, 15);
var end = new Date(mid.getFullYear(), mid.getMonth() + 1, 15);
var startId = Rec.getMonthId(start);
var midId = Rec.getMonthId(mid);
var endId = Rec.getMonthId(end);
var toAdd = Rec.getRecurring([ startId, midId, endId ], [ ev ]);
var all = [ ev ];
Array.prototype.push.apply(all, toAdd);
return Rec.applyUpdates(all);
};
var clearDismissed = function(ctx, uid) {
var h = Util.find(ctx, [ "store", "proxy", "hideReminders" ]) || {};
Object.keys(h).filter((function(id) {
return id === uid;
})).forEach((function(id) {
delete h[id];
}));
};
var _updateEventReminders = function(ctx, reminders, _ev, useLastVisit) {
var now = +new Date;
var ev = Util.clone(_ev);
var uid = ev.id;
if (Array.isArray(reminders[uid])) {
reminders[uid].forEach((function(to) {
clearTimeout(to);
}));
}
reminders[uid] = [];
if (_ev.deleted) {
return;
}
var d = Util.find(ctx, [ "store", "proxy", "hideReminders", uid ]) || [];
var last = ctx.store.data.lastVisit;
if (ev.isAllDay) {
if (ev.startDay) {
ev.start = +FP.parseDate(ev.startDay);
}
if (ev.endDay) {
var endDate = FP.parseDate(ev.endDay);
endDate.setHours(23);
endDate.setMinutes(59);
endDate.setSeconds(59);
ev.end = +endDate;
}
}
var oneWeekAgo = now - 7 * 24 * 3600 * 1e3;
var missed = useLastVisit && ev.start > last && ev.end <= now && ev.end > oneWeekAgo;
if (ev.end <= now && !missed) {
delete reminders[uid];
clearDismissed(ctx, uid);
return;
}
var send = function(d) {
var hide = Util.find(ctx, [ "store", "proxy", "settings", "general", "calendar", "hideNotif" ]);
if (hide) {
return;
}
var ctime = ev.start <= now ? ev.start : +new Date;
ctx.store.mailbox.showMessage("reminders", {
msg: {
ctime,
type: "REMINDER",
missed: Boolean(missed),
content: ev
},
hash: "REMINDER|" + uid + "-" + d
}, null, (function() {}));
};
var sent = false;
var sendNotif = function(delay) {
sent = true;
ctx.Store.onReadyEvt.reg((function() {
send(delay);
}));
};
var notifs = ev.reminders || [];
notifs.sort((function(a, b) {
return a - b;
}));
notifs.some((function(delayMinutes) {
var delay = delayMinutes * 6e4;
var time = now + delay;
if (d.some((function(minutes) {
return delayMinutes >= minutes;
}))) {
return;
}
if (ev.start - time >= 2147483647) {
return true;
}
if (ev.start <= time) {
sendNotif(delayMinutes);
return true;
}
reminders[uid].push(setTimeout((function() {
sendNotif(delayMinutes);
}), ev.start - time));
}));
if (!sent) {
ctx.Store.onReadyEvt.reg((function() {
ctx.store.mailbox.hideMessage("reminders", {
hash: "REMINDER|" + uid
}, null, (function() {}));
}));
}
};
var updateEventReminders = function(ctx, reminders, ev, useLastVisit) {
var all = getRecurring(Util.clone(ev));
all.forEach((function(_ev) {
_updateEventReminders(ctx, reminders, _ev, useLastVisit);
}));
};
var addReminders = function(ctx, id, ev) {
var calendar = ctx.calendars[id];
if (!ev) {
return;
}
if (!calendar || !calendar.reminders) {
return;
}
if (calendar.stores.length === 1 && calendar.stores[0] === 0) {
return;
}
updateEventReminders(ctx, calendar.reminders, ev);
};
var addInitialReminders = function(ctx, id, useLastVisit) {
var calendar = ctx.calendars[id];
if (!calendar || !calendar.reminders) {
return;
}
if (Object.keys(calendar.reminders).length) {
return;
}
if (calendar.stores.length === 1 && calendar.stores[0] === 0) {
return;
}
var content = Util.find(calendar, [ "proxy", "content" ]);
if (!content) {
return;
}
Object.keys(content).forEach((function(uid) {
updateEventReminders(ctx, calendar.reminders, content[uid], useLastVisit);
}));
};
var openChannel = function(ctx, cfg, _cb) {
var cb = Util.once(Util.mkAsync(_cb || function() {}));
var teamId = cfg.storeId;
var data = cfg.data;
var channel = data.channel;
if (!channel) {
return;
}
var c = ctx.calendars[channel];
var update = function() {
sendUpdate(ctx, c);
};
if (c) {
if (c.readOnly && data.href) {
var upgradeParsed = Hash.parsePadUrl(data.href);
var upgradeSecret = Hash.getSecrets("calendar", upgradeParsed.hash, data.password);
var upgradeCrypto = Crypto.createEncryptor(upgradeSecret.keys);
c.hashes.editHash = Hash.getEditHashFromKeys(upgradeSecret);
c.lm.setReadOnly(false, upgradeCrypto);
c.readOnly = false;
} else if (teamId === 0) {
if (c.stores.length === 1 && c.stores[0] === 0 && c.tempId.length && cfg.cId) {
c.tempId.push(cfg.cId);
}
return void cb();
}
if (c.roStores.indexOf(teamId) !== -1 && data.href) {
c.roStores.splice(c.roStores.indexOf(teamId), 1);
if (c.stores.indexOf(0) !== -1) {
c.stores.splice(c.stores.indexOf(0), 1);
}
update();
}
if (c.stores && c.stores.indexOf(teamId) !== -1) {
return void cb();
}
if (c.stores.indexOf(0) !== -1) {
c.stores.splice(c.stores.indexOf(0), 1);
c.tempId = [];
}
c.stores.push(teamId);
if (!data.href) {
c.roStores.push(teamId);
}
update();
return void cb();
}
c = ctx.calendars[channel] = {
ready: false,
channel,
readOnly: !data.href,
tempId: [],
stores: [ teamId ],
roStores: data.href ? [] : [ teamId ],
reminders: {},
hashes: {}
};
if (teamId === 0) {
c.tempId.push(cfg.cId);
}
var parsed = Hash.parsePadUrl(data.href || data.roHref);
var secret = Hash.getSecrets("calendar", parsed.hash, data.password);
var crypto = Crypto.createEncryptor(secret.keys);
c.hashes.viewHash = Hash.getViewHashFromKeys(secret);
if (data.href) {
c.hashes.editHash = Hash.getEditHashFromKeys(secret);
}
c.proxy = {
metadata: {
color: data.color,
title: data.title
}
};
update();
var onDeleted = function() {
c.stores.forEach((function(storeId) {
var store = getStore(ctx, storeId);
if (!store || !store.rpc || !store.proxy.calendars) {
return;
}
delete store.proxy.calendars[channel];
var unpin = store.unpin || ctx.unpinPads;
unpin([ channel ], (function(res) {
if (res && res.error) {
console.error(res.error);
}
}));
}));
if (c.lm) {
c.lm.stop();
}
c.stores = [];
sendUpdate(ctx, c);
clearReminders(ctx, channel);
delete ctx.calendars[channel];
};
nThen((function(waitFor) {
if (!ctx.store.network || cfg.isNew) {
return;
}
ctx.Store.isNewChannel(null, channel, waitFor((function(obj) {
if (obj && obj.error) {
return;
}
if (obj && typeof obj.isNew === "boolean") {
if (obj.isNew) {
onDeleted();
cb({
error: "EDELETED"
});
waitFor.abort();
return;
}
}
})));
})).nThen((function() {
var edPublic;
if (teamId === 1 || !teamId) {
edPublic = ctx.store.proxy.edPublic;
} else {
var teams = ctx.store.modules.team && ctx.store.modules.team.getTeamsData();
var team = teams && teams[teamId];
edPublic = team ? team.edPublic : undefined;
}
var config = {
data: {},
network: ctx.store.network || ctx.store.networkPromise,
channel: secret.channel,
crypto,
owners: [ edPublic ],
ChainPad,
validateKey: secret.keys.validateKey || undefined,
userName: "calendar",
Cache,
classic: true,
onRejected: ctx.Store && ctx.Store.onRejected
};
var lm = Listmap.create(config);
c.lm = lm;
var proxy = c.proxy = lm.proxy;
var _updateCalled = false;
var _update = function() {
if (_updateCalled) {
return;
}
_updateCalled = true;
setTimeout((function() {
_updateCalled = false;
update();
}));
};
lm.proxy.on("cacheready", (function() {
if (!proxy.metadata) {
return;
}
c.cacheready = true;
_update();
if (cb) {
cb(null, lm.proxy);
}
addInitialReminders(ctx, channel, cfg.lastVisitNotif);
})).on("ready", (function(info) {
var md = info.metadata;
c.owners = md.owners || [];
c.ready = true;
if (!proxy.metadata) {
if (!cfg.isNew) {
return void onDeleted();
}
proxy.metadata = {
color: data.color,
title: data.title
};
}
_update();
if (cb) {
cb(null, lm.proxy);
}
addInitialReminders(ctx, channel, cfg.lastVisitNotif);
})).on("change", [], (function() {
if (!c.ready) {
return;
}
_update();
})).on("change", [ "content" ], (function(o, n, p) {
if (p.length === 2 && n && !o) {
return void addReminders(ctx, channel, n);
}
if (p.length === 2 && !n && o) {
return void addReminders(ctx, channel, {
id: p[1],
start: 0
});
}
if (p.length >= 3 && [ "start", "reminders", "isAllDay" ].includes(p[2])) {
return void setTimeout((function() {
addReminders(ctx, channel, proxy.content[p[1]]);
}));
}
if (p.length >= 6 && [ "start", "reminders", "isAllDay" ].includes(p[5])) {
return void setTimeout((function() {
addReminders(ctx, channel, proxy.content[p[1]]);
}));
}
})).on("remove", [ "content" ], (function(x, p) {
_update();
if (p.length >= 3 && p[2] === "reminders" || p.length >= 6 && p[5] === "reminders") {
return void setTimeout((function() {
addReminders(ctx, channel, proxy.content[p[1]]);
}));
}
})).on("change", [ "metadata" ], (function() {
var md = proxy.metadata;
if (!md || !md.title || !md.color) {
return;
}
updateLocalCalendars(ctx, c, md);
})).on("disconnect", (function() {
c.offline = true;
_update();
})).on("reconnect", (function() {
c.offline = false;
_update();
})).on("error", (function(info) {
if (!info || !info.error) {
return;
}
if (info.error === "EDELETED") {
return void onDeleted();
}
if (info.error === "ERESTRICTED") {
c.restricted = true;
_update();
}
cb(info);
}));
}));
};
var decryptTeamCalendarHref = function(store, calData) {
if (!calData.href) {
return;
}
if (calData.href.indexOf("#") !== -1) {
return;
}
if (store.secondaryKey) {
try {
calData.href = store.userObject.cryptor.decrypt(calData.href);
} catch (e) {
console.error(e);
delete calData.href;
}
} else {
delete calData.href;
}
};
var initializeStore = function(ctx, store) {
var c = store.proxy.calendars;
var storeId = store.id || 1;
store.proxy.on("change", [ "calendars" ], (function(o, n, p) {
if (p.length < 2) {
return;
}
if (o && !n) {
(function() {
var id = p[1];
var ctxCal = ctx.calendars[id];
if (!ctxCal) {
return;
}
var idx = ctxCal.stores.indexOf(storeId);
if (idx === -1) {
return;
}
ctxCal.stores.splice(idx, 1);
var roIdx = ctxCal.roStores.indexOf(storeId);
if (roIdx !== -1) {
ctxCal.roStores.splice(roIdx, 1);
}
closeCalendar(ctx, id);
sendUpdate(ctx, ctxCal);
})();
}
if (!o && n) {
(function() {
var id = p[1];
var _cal = store.proxy.calendars[id];
if (!_cal) {
return;
}
var cal = Util.clone(_cal);
decryptTeamCalendarHref(store, cal);
openChannel(ctx, {
storeId,
data: cal
});
})();
}
}));
Object.keys(c || {}).forEach((function(channel) {
var cal = Util.clone(c[channel]);
decryptTeamCalendarHref(store, cal);
openChannel(ctx, {
storeId,
lastVisitNotif: true,
data: cal
});
}));
};
var openChannels = function(ctx) {
initializeStore(ctx, ctx.store);
var teams = ctx.store.modules.team && ctx.store.modules.team.getTeamsData();
if (!teams) {
return;
}
Object.keys(teams).forEach((function(id) {
var store = getStore(ctx, id);
initializeStore(ctx, store);
}));
};
var subscribe = function(ctx, data, cId, cb) {
var idx = ctx.clients.indexOf(cId);
if (idx === -1) {
ctx.clients.push(cId);
}
cb({
length: Object.keys(ctx.calendars).length
});
Object.keys(ctx.calendars).forEach((function(channel) {
var c = ctx.calendars[channel] || {};
sendUpdate(ctx, c);
}));
};
var importICSCalendar = function(ctx, data, cId, cb) {
var id = data.id;
var c = ctx.calendars[id];
if (!c || !c.proxy) {
return void cb({
error: "ENOENT"
});
}
var json = data.json;
c.proxy.content = c.proxy.content || {};
Object.keys(json).forEach((function(uid) {
c.proxy.content[uid] = json[uid];
addReminders(ctx, id, json[uid]);
}));
Realtime.whenRealtimeSyncs(c.lm.realtime, (function() {
sendUpdate(ctx, c);
cb();
}));
};
var openCalendar = function(ctx, data, cId, cb) {
var secret = Hash.getSecrets("calendar", data.hash, data.password);
var hash = Hash.getEditHashFromKeys(secret);
var roHash = Hash.getViewHashFromKeys(secret);
var cal = {
href: hash && Hash.hashToHref(hash, "calendar"),
roHref: roHash && Hash.hashToHref(roHash, "calendar"),
channel: secret.channel,
color: Util.getRandomColor(),
title: "..."
};
openChannel(ctx, {
cId,
storeId: 0,
data: cal
}, cb);
};
var importCalendar = function(ctx, data, cId, cb) {
var id = data.id;
var c = ctx.calendars[id];
if (!c) {
return void cb({
error: "ENOENT"
});
}
if (!Array.isArray(c.stores) || c.stores.indexOf(data.teamId) === -1) {
return void cb({
error: "EINVAL"
});
}
var store = ctx.store;
var calendars = store.proxy.calendars = store.proxy.calendars || {};
var hash = c.hashes.editHash;
var roHash = c.hashes.viewHash;
calendars[id] = {
href: hash && Hash.hashToHref(hash, "calendar"),
roHref: roHash && Hash.hashToHref(roHash, "calendar"),
channel: id,
color: Util.find(c, [ "proxy", "metadata", "color" ]) || Util.getRandomColor(),
title: Util.find(c, [ "proxy", "metadata", "title" ]) || "..."
};
ctx.Store.onSync(null, cb);
openChannel(ctx, {
storeId: 1,
data: {
href: calendars[id].href,
toHref: calendars[id].roHref,
channel: id
}
});
};
var addCalendar = function(ctx, data, cId, cb) {
var store = getStore(ctx, data.teamId);
if (!store) {
return void cb({
error: "NO_STORE"
});
}
if (!store.rpc) {
return void cb({
error: "EFORBIDDEN"
});
}
var c = store.proxy.calendars = store.proxy.calendars || {};
var parsed = Hash.parsePadUrl(data.href);
var secret = Hash.getSecrets(parsed.type, parsed.hash, data.password);
if (secret.channel !== data.channel) {
return void cb({
error: "EINVAL"
});
}
var hash = Hash.getEditHashFromKeys(secret);
var roHash = Hash.getViewHashFromKeys(secret);
var href = hash && Hash.hashToHref(hash, "calendar");
var cal = {
href,
roHref: roHash && Hash.hashToHref(roHash, "calendar"),
color: data.color,
title: data.title,
channel: data.channel
};
if (c[data.channel] && (c[data.channel].href || !cal.href)) {
return void cb();
}
cal.color = data.color;
cal.title = data.title;
openChannel(ctx, {
storeId: store.id || 1,
data: Util.clone(cal)
}, (function(err) {
if (err) {
console.error(err);
return void cb({
error: err.error
});
}
if (href && store.id && store.secondaryKey) {
try {
cal.href = store.userObject.cryptor.encrypt(href);
} catch (e) {
console.error(e);
}
}
c[cal.channel] = cal;
var pin = store.pin || ctx.pinPads;
pin([ cal.channel ], (function(res) {
if (res && res.error) {
console.error(res.error);
}
}));
ctx.Store.onSync(store.id, cb);
}));
};
var createCalendar = function(ctx, data, cId, cb) {
var store = getStore(ctx, data.teamId);
if (!store) {
return void cb({
error: "NO_STORE"
});
}
if (!store.rpc) {
return void cb({
error: "EFORBIDDEN"
});
}
var c = store.proxy.calendars = store.proxy.calendars || {};
var cal = makeCalendar();
cal.color = data.color;
cal.title = data.title;
openChannel(ctx, {
storeId: store.id || 1,
data: cal,
isNew: true
}, (function(err) {
if (err) {
console.error(err);
return void cb({
error: err.error
});
}
var ctxCal = ctx.calendars[cal.channel];
Realtime.whenRealtimeSyncs(ctxCal.lm.realtime, (function() {
c[cal.channel] = cal;
var pin = store.pin || ctx.pinPads;
pin([ cal.channel ], (function(res) {
if (res && res.error) {
console.error(res.error);
}
}));
ctx.Store.onSync(store.id, cb);
}));
}));
};
var updateCalendar = function(ctx, data, cId, cb) {
var id = data.id;
var c = ctx.calendars[id];
if (!c) {
return void cb({
error: "ENOENT"
});
}
var md = Util.find(c, [ "proxy", "metadata" ]);
if (!md) {
return void cb({
error: "EINVAL"
});
}
md.title = data.title;
md.color = data.color;
Realtime.whenRealtimeSyncs(c.lm.realtime, cb);
sendUpdate(ctx, c);
updateLocalCalendars(ctx, c, data);
};
var deleteCalendar = function(ctx, data, cId, cb) {
var store = getStore(ctx, data.teamId);
if (!store) {
return void cb({
error: "NO_STORE"
});
}
if (!store.rpc) {
return void cb({
error: "EFORBIDDEN"
});
}
if (!store.proxy.calendars) {
return;
}
var id = data.id;
var cal = store.proxy.calendars[id];
if (!cal) {
return void cb();
}
delete store.proxy.calendars[id];
var unpin = store.unpin || ctx.unpinPads;
unpin([ id ], (function(res) {
if (res && res.error) {
console.error(res.error);
}
}));
var ctxCal = ctx.calendars[id];
var idx = ctxCal.stores.indexOf(store.id || 1);
ctxCal.stores.splice(idx, 1);
closeCalendar(ctx, id);
ctx.Store.onSync(store.id, (function() {
sendUpdate(ctx, ctxCal);
cb();
}));
};
var createEvent = function(ctx, data, cId, cb) {
var id = data.calendarId;
var c = ctx.calendars[id];
if (!c) {
return void cb({
error: "ENOENT"
});
}
var startDate = new Date(data.start);
var endDate = new Date(data.end);
if (data.isAllDay) {
data.startDay = startDate.getFullYear() + "-" + (startDate.getMonth() + 1) + "-" + startDate.getDate();
data.endDay = endDate.getFullYear() + "-" + (endDate.getMonth() + 1) + "-" + endDate.getDate();
} else {
delete data.startDay;
delete data.endDay;
}
c.proxy.content = c.proxy.content || {};
c.proxy.content[data.id] = data;
Realtime.whenRealtimeSyncs(c.lm.realtime, (function() {
addReminders(ctx, id, data);
sendUpdate(ctx, c);
cb();
}));
};
var updateEvent = function(ctx, data, cId, cb) {
if (!data || !data.ev) {
return void cb({
error: "EINVAL"
});
}
var id = data.ev.calendarId;
var c = ctx.calendars[id];
if (!c || !c.proxy || !c.proxy.content) {
return void cb({
error: "ENOENT"
});
}
var ev = c.proxy.content[data.ev.id];
if (!ev) {
return void cb({
error: "EINVAL"
});
}
data.rawData = data.rawData || {};
var changes = data.changes || {};
var type = data.type || {};
var newC;
if (changes.calendarId) {
newC = ctx.calendars[changes.calendarId];
if (!newC || !newC.proxy) {
return void cb({
error: "ENOENT"
});
}
newC.proxy.content = newC.proxy.content || {};
}
var RECUPDATE = {
one: {},
from: {}
};
if ([ "one", "from", "all" ].includes(type.which)) {
ev.recUpdate = ev.recUpdate || RECUPDATE;
if (!ev.recUpdate.one) {
ev.recUpdate.one = {};
}
if (!ev.recUpdate.from) {
ev.recUpdate.from = {};
}
}
var update = ev.recUpdate;
var alwaysAll = [ "calendarId" ];
var keys = Object.keys(changes).filter((function(s) {
return !alwaysAll.includes(s);
}));
var cleanAfter = function(time) {
[ update.from, update.one ].forEach((function(obj) {
Object.keys(obj).forEach((function(d) {
if (Number(d) < time) {
return;
}
delete obj[d];
}));
}));
};
var cleanKeys = function(obj, when) {
Object.keys(obj).forEach((function(d) {
if (when && Number(d) < when) {
return;
}
keys.forEach((function(k) {
delete obj[d][k];
}));
}));
};
var dontSendUpdate = false;
if (typeof changes.recurrenceRule !== "undefined") {
if (type.which === "all" && changes.recurrenceRule.until) {
cleanAfter(changes.recurrenceRule.until);
} else if ([ "one", "from" ].includes(type.which) && !data.rawData.isOrigin) {
cleanAfter(type.when + 1);
} else {
update = ev.recUpdate = RECUPDATE;
}
}
if (type.which === "one") {
update.one[type.when] = update.one[type.when] || {};
} else if (type.which === "from") {
update.from[type.when] = update.from[type.when] || {};
cleanKeys(update.from, type.when);
cleanKeys(update.one, type.when);
} else if (type.which === "all") {
cleanKeys(update.from);
cleanKeys(update.one);
}
if (changes.start && update && (!type.which || type.which === "all")) {
var diff = changes.start - ev.start;
var newOne = {};
var newFrom = {};
Object.keys(update.one || {}).forEach((function(time) {
newOne[Number(time) + diff] = update.one[time];
}));
Object.keys(update.from || {}).forEach((function(time) {
newFrom[Number(time) + diff] = update.from[time];
}));
update.one = newOne;
update.from = newFrom;
}
var h = Util.find(ctx, [ "store", "proxy", "hideReminders" ]) || {};
if (changes.reminders) {
if (type.which === "one") {
if (!type.when || type.when === ev.start) {
delete h[data.ev.id];
} else {
delete h[data.ev.id + "|" + type.when];
}
} else if (type.which === "from") {
Object.keys(h).filter((function(id) {
return id.indexOf(data.ev.id) === 0;
})).forEach((function(id) {
var time = Number(id.split("|")[1]);
if (!time) {
return;
}
if (time < type.when) {
return;
}
delete h[id];
}));
} else {
Object.keys(h).filter((function(id) {
return id.indexOf(data.ev.id) === 0;
})).forEach((function(id) {
delete h[id];
}));
}
}
Object.keys(changes).forEach((function(key) {
if (!alwaysAll.includes(key) && type.which === "one") {
if (key === "recurrenceRule") {
if (data.rawData && data.rawData.isOrigin) {
return ev[key] = changes[key];
}
update.from[type.when] = update.from[type.when] || {};
return update.from[type.when][key] = changes[key];
}
update.one[type.when][key] = changes[key];
return;
}
if (!alwaysAll.includes(key) && type.which === "from") {
update.from[type.when][key] = changes[key];
return;
}
ev[key] = changes[key];
}));
var startDate = new Date(ev.start);
var endDate = new Date(ev.end);
if (ev.isAllDay) {
ev.startDay = startDate.getFullYear() + "-" + (startDate.getMonth() + 1) + "-" + startDate.getDate();
ev.endDay = endDate.getFullYear() + "-" + (endDate.getMonth() + 1) + "-" + endDate.getDate();
} else {
delete ev.startDay;
delete ev.endDay;
}
if (changes.calendarId && newC) {
newC.proxy.content[data.ev.id] = Util.clone(ev);
delete c.proxy.content[data.ev.id];
}
nThen((function(waitFor) {
Realtime.whenRealtimeSyncs(c.lm.realtime, waitFor());
if (newC) {
Realtime.whenRealtimeSyncs(newC.lm.realtime, waitFor());
}
})).nThen((function() {
if (newC) {
addReminders(ctx, id, {
id: ev.id,
start: 0
});
addReminders(ctx, ev.calendarId, ev);
} else if (changes.start || changes.reminders || changes.isAllDay) {
addReminders(ctx, id, ev);
}
{
sendUpdate(ctx, c);
}
if (newC && !dontSendUpdate) {
sendUpdate(ctx, newC);
}
cb();
}));
};
var deleteEvent = function(ctx, data, cId, cb) {
var id = data.calendarId;
var c = ctx.calendars[id];
if (!c) {
return void cb({
error: "ENOENT"
});
}
c.proxy.content = c.proxy.content || {};
var evId = data.id.split("|")[0];
if (data.id === evId) {
delete c.proxy.content[data.id];
} else {
var ev = c.proxy.content[evId];
var s = data.raw && data.raw.start;
if (s) {
ev.recUpdate = ev.recUpdate || {
one: {},
from: {}
};
ev.recUpdate.one[s] = {
deleted: true
};
}
}
Realtime.whenRealtimeSyncs(c.lm.realtime, (function() {
addReminders(ctx, id, {
id: data.id,
start: 0
});
sendUpdate(ctx, c);
cb();
}));
};
var removeClient = function(ctx, cId) {
var idx = ctx.clients.indexOf(cId);
if (idx !== -1) {
ctx.clients.splice(idx, 1);
}
Object.keys(ctx.calendars).forEach((function(id) {
var cal = ctx.calendars[id];
if (cal.stores.length !== 1 || cal.stores[0] !== 0 || !cal.tempId.length) {
return;
}
var idx = cal.tempId.indexOf(cId);
if (idx !== -1) {
cal.tempId.splice(idx, 1);
}
if (!cal.tempId.length) {
cal.stores = [];
closeCalendar(ctx, id);
}
}));
};
Calendar.init = function(cfg, waitFor, emit) {
var calendar = {};
var store = cfg.store;
var ctx = {
loggedIn: store.loggedIn && store.proxy.edPublic,
store,
Store: cfg.Store,
pinPads: cfg.pinPads,
unpinPads: cfg.unpinPads,
updateMetadata: cfg.updateMetadata,
emit,
onReady: Util.mkEvent(true),
calendars: {},
clients: []
};
initializeCalendars(ctx, waitFor((function(err) {
if (err) {
return;
}
openChannels(ctx);
})));
ctx.store.proxy.on("change", [ "hideReminders" ], (function(o, n, p) {
var uid = p[1].split("|")[0];
Object.keys(ctx.calendars).some((function(calId) {
var c = ctx.calendars[calId];
if (!c || !c.proxy || !c.proxy.content) {
return;
}
if (c.proxy.content[uid]) {
setTimeout((function() {
addReminders(ctx, calId, c.proxy.content[uid]);
}));
return true;
}
}));
}));
calendar.closeTeam = function(teamId) {
Object.keys(ctx.calendars).forEach((function(id) {
var ctxCal = ctx.calendars[id];
var idx = ctxCal.stores.indexOf(teamId);
if (idx === -1) {
return;
}
ctxCal.stores.splice(idx, 1);
var roIdx = ctxCal.roStores.indexOf(teamId);
if (roIdx !== -1) {
ctxCal.roStores.splice(roIdx, 1);
}
closeCalendar(ctx, id);
sendUpdate(ctx, ctxCal);
}));
};
calendar.openTeam = function(teamId) {
var store = getStore(ctx, teamId);
if (!store) {
return;
}
initializeStore(ctx, store);
};
calendar.upgradeTeam = function(teamId) {
if (!teamId) {
return;
}
var store = getStore(ctx, teamId);
if (!store) {
return;
}
Object.keys(ctx.calendars).forEach((function(id) {
var ctxCal = ctx.calendars[id];
var idx = ctxCal.stores.indexOf(teamId);
if (idx === -1) {
return;
}
var _cal = store.proxy.calendars[id];
var cal = Util.clone(_cal);
decryptTeamCalendarHref(store, cal);
openChannel(ctx, {
storeId: teamId,
data: cal
});
sendUpdate(ctx, ctxCal);
}));
};
calendar.removeClient = function(clientId) {
removeClient(ctx, clientId);
};
calendar.execCommand = function(clientId, obj, cb) {
var cmd = obj.cmd;
var data = obj.data;
if (cmd === "SUBSCRIBE") {
return void subscribe(ctx, data, clientId, cb);
}
if (cmd === "OPEN") {
ctx.Store.onReadyEvt.reg((function() {
openCalendar(ctx, data, clientId, cb);
}));
return;
}
if (cmd === "IMPORT") {
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
if (!ctx.loggedIn) {
return void cb({
error: "NOT_LOGGED_IN"
});
}
return void importCalendar(ctx, data, clientId, cb);
}
if (cmd === "IMPORT_ICS") {
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
return void importICSCalendar(ctx, data, clientId, cb);
}
if (cmd === "ADD") {
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
if (!ctx.loggedIn) {
return void cb({
error: "NOT_LOGGED_IN"
});
}
return void addCalendar(ctx, data, clientId, cb);
}
if (cmd === "CREATE") {
if (!ctx.loggedIn) {
return void cb({
error: "NOT_LOGGED_IN"
});
}
if (data.initialCalendar) {
return void ctx.Store.onReadyEvt.reg((function() {
createCalendar(ctx, data, clientId, cb);
}));
}
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
return void createCalendar(ctx, data, clientId, cb);
}
if (cmd === "UPDATE") {
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
return void updateCalendar(ctx, data, clientId, cb);
}
if (cmd === "DELETE") {
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
if (!ctx.loggedIn) {
return void cb({
error: "NOT_LOGGED_IN"
});
}
return void deleteCalendar(ctx, data, clientId, cb);
}
if (cmd === "CREATE_EVENT") {
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
return void createEvent(ctx, data, clientId, cb);
}
if (cmd === "UPDATE_EVENT") {
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
return void updateEvent(ctx, data, clientId, cb);
}
if (cmd === "DELETE_EVENT") {
if (ctx.store.offline) {
return void cb({
error: "OFFLINE"
});
}
return void deleteEvent(ctx, data, clientId, cb);
}
};
return calendar;
};
return Calendar;
};
if (module.exports) {
module.exports = factory(requireCommonUtil(), requireCommonHash(), requireCommonConstants(), requireCommonRealtime(), requireCacheStore(), requireRecurrence(), requireNthen(), requireChainpadListmap(), requireFlatpickr(), requireCrypto(), requireChainpad_dist());
}
})();
})(calendar$1);
return calendar$1.exports;
}
var hasRequiredAsyncStore;
function requireAsyncStore() {
if (hasRequiredAsyncStore) return asyncStore$1.exports;
hasRequiredAsyncStore = 1;
(function(module) {
(() => {
const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager, Migrate, Hash, Util, Constants, Feedback, Realtime, Messaging, Pinpad, Rpc, Merge, Cache, SF, AccountTS, DriveTS, Cursor, Support, Integration, OnlyOffice, Mailbox, Profile, Team, Messenger, History, Calendar, Block, NetConfig, AppConfig = {}, Crypto, ChainPad, CpNetflux, Listmap, Netflux, nThen) => {
const Account = AccountTS.Account;
const Drive = DriveTS.Drive;
const window = globalThis;
globalThis.nacl = globalThis.nacl || Crypto.Nacl;
const Saferphore = Util.Saferphore;
var onReadyEvt = Util.mkEvent(true);
var onCacheReadyEvt = Util.mkEvent(true);
var onJoinedEvt = Util.mkEvent(true);
var onPadRejectedEvt = Util.mkEvent(true);
const setCustomize = data => {
ApiConfig = data.ApiConfig;
AppConfig = data.AppConfig;
};
var CACHE_MAX_AGE = 90;
var NEW_USER_SETTINGS = {
drive: {
hideDuplicate: true
},
pad: {
width: true,
spellcheck: true
},
security: {
unsafeLinks: false
},
general: {
allowUserFeedback: true
}
};
var create = function(config) {
var Store = window.Cryptpad_Store = {};
let postMessage = config.query || function() {};
let broadcast = config.broadcast || function() {};
var store = window.CryptPad_AsyncStore = {
modules: {}
};
Store.onReadyEvt = onReadyEvt;
var driveEventClients = [];
var sendDriveEvent = function(q, data, sender) {
driveEventClients.forEach((function(cId) {
if (cId === sender) {
return;
}
postMessage(cId, q, data);
}));
};
var getStore = function(teamId) {
if (!teamId) {
return store;
}
try {
var teams = store.modules["team"];
var team = teams.getTeam(teamId);
if (!team) {
console.error("Team not found", teamId);
return;
}
return team;
} catch (e) {
console.error(e);
console.error("Team not found", teamId);
return;
}
};
var onSync = Store.onSync = function(teamId, cb) {
var s = getStore(teamId);
if (!s) {
return void cb({
error: "ENOTFOUND"
});
}
nThen((function(waitFor) {
if (s.realtime) {
Realtime.whenRealtimeSyncs(s.realtime, waitFor());
}
if (!s.id && s.drive?.realtime) {
Realtime.whenRealtimeSyncs(s.drive.realtime, waitFor());
}
if (s.sharedFolders && typeof s.sharedFolders === "object") {
for (var k in s.sharedFolders) {
if (!s.sharedFolders[k].realtime) {
continue;
}
Realtime.whenRealtimeSyncs(s.sharedFolders[k].realtime, waitFor());
}
}
})).nThen((function() {
cb();
}));
};
Store.get = function(clientId, data, cb) {
var s = getStore(data.teamId);
if (!s) {
return void cb({
error: "ENOTFOUND"
});
}
if (!s.proxy) {
return void cb({
error: "ENODRIVE"
});
}
cb(Util.find(s.proxy, data.key));
};
Store.set = function(clientId, data, cb) {
var s = getStore(data.teamId);
if (!s) {
return void cb({
error: "ENOTFOUND"
});
}
if (!s.proxy) {
return void cb({
error: "ENODRIVE"
});
}
var path = data.key.slice();
var key = path.pop();
var obj = Util.find(s.proxy, path);
if (!obj || typeof obj !== "object") {
return void cb({
error: "INVALID_PATH"
});
}
if (typeof data.value === "undefined") {
delete obj[key];
} else {
obj[key] = data.value;
}
if (!data.teamId) {
broadcast([ clientId ], "UPDATE_METADATA");
if (Array.isArray(path) && path[0] === "profile" && store.messenger) {
Messaging.updateMyData(store);
}
}
onSync(data.teamId, cb);
};
const copyObject = (src, target) => {
Object.keys(src).forEach((k => {
delete src[k];
}));
Object.keys(target).forEach((k => {
src[k] = Util.clone(target[k]);
}));
};
const getProxy = teamId => {
let proxy;
if (!teamId) {
proxy = store.drive?.proxy;
} else {
const s = getStore(teamId);
proxy = s?.drive?.proxy;
}
return proxy;
};
Store.drive = {
get: (clientId, data, cb) => {
let proxy = getProxy(data.teamId);
if (!proxy) {
return void cb({
error: "ENOTFOUND"
});
}
cb(proxy);
},
set: (clientId, data, cb) => {
let proxy = getProxy(data.teamId);
if (!proxy) {
return void cb({
error: "ENOTFOUND"
});
}
copyObject(proxy, data.value);
onSync(data.teamId, cb);
}
};
Store.getSharedFolder = function(clientId, data, cb) {
var s = getStore(data.teamId);
var id = data.id;
var proxy;
if (!s || !s.manager) {
return void cb({
error: "ENOTFOUND"
});
}
if (s.manager.folders[id]) {
proxy = Util.clone(s.manager.folders[id].proxy);
proxy.offline = Boolean(s.manager.folders[id].offline);
return void cb(proxy);
} else {
var shared = Util.find(s.proxy, [ "drive", UserObject.SHARED_FOLDERS ]) || {};
if (shared[id]) {
return void Store.loadSharedFolder(data.teamId, id, shared[id], (function() {
cb(s.manager.folders[id].proxy);
}));
}
}
cb({});
};
Store.restoreSharedFolder = function(clientId, data, cb) {
if (!data.sfId || !data.drive) {
return void cb({
error: "EINVAL"
});
}
var s = getStore(data.teamId);
if (s.sharedFolders[data.sfId]) {
Object.keys(data.drive).forEach((function(k) {
s.sharedFolders[data.sfId].proxy[k] = data.drive[k];
}));
Object.keys(s.sharedFolders[data.sfId].proxy).forEach((function(k) {
if (data.drive[k]) {
return;
}
delete s.sharedFolders[data.sfId].proxy[k];
}));
}
onSync(data.teamId, cb);
};
Store.hasSigningKeys = function() {
if (!store.proxy) {
return;
}
return typeof store.proxy.edPrivate === "string" && typeof store.proxy.edPublic === "string";
};
Store.hasCurveKeys = function() {
if (!store.proxy) {
return;
}
return typeof store.proxy.curvePrivate === "string" && typeof store.proxy.curvePublic === "string";
};
Store.isOwned = function(owners) {
var edPublic = store.proxy.edPublic;
if (!edPublic) {
return false;
}
if (!Array.isArray(owners) || !owners.length) {
return false;
}
if (owners.indexOf(edPublic) !== -1) {
return true;
}
var teams = store.proxy.teams;
if (!teams) {
return false;
}
return Object.keys(teams).some((function(id) {
var ed = Util.find(teams[id], [ "keys", "drive", "edPublic" ]);
return ed && owners.indexOf(ed) !== -1;
}));
};
var getUserChannelList = function() {
var userChannel = `${store.driveChannel}#drive`;
if (!userChannel) {
return null;
}
var list = store.manager.getChannelsList("pin");
var profile = store.proxy.profile;
if (profile) {
var profileChan = profile.edit ? Hash.hrefToHexChannelId("/profile/#" + profile.edit, null) : null;
if (profileChan) {
list.push(profileChan);
}
var avatarChan = profile.avatar ? Hash.hrefToHexChannelId(profile.avatar, null) : null;
if (avatarChan) {
list.push(avatarChan);
}
}
if (store.proxy.todo) {
list.push(Hash.hrefToHexChannelId("/todo/#" + store.proxy.todo, null));
}
if (store.proxy.friends) {
var fList = Messaging.getFriendChannelsList(store.proxy);
list = list.concat(fList);
}
if (store.proxy.mailboxes) {
var mList = Object.keys(store.proxy.mailboxes).map((function(m) {
if (m === "broadcast" && !store.isAdmin) {
return;
}
return store.proxy.mailboxes[m].channel;
})).filter(Boolean);
list = list.concat(mList);
}
if (store.proxy.calendars) {
var cList = Object.keys(store.proxy.calendars).map((function(c) {
return store.proxy.calendars[c].channel;
}));
list = list.concat(cList);
}
list.push(userChannel);
if (store.data && store.data.blockId) {
list.push(`${store.data.blockId}#block`);
}
list.sort();
return list;
};
var getExpirableChannelList = function() {
return store.manager.getChannelsList("expirable");
};
var getCanonicalChannelList = function(expirable) {
var list = expirable ? getExpirableChannelList() : getUserChannelList();
return Util.deduplicateString(list).sort();
};
Store.pinPads = function(clientId, data, cb) {
if (!data) {
return void cb({
error: "EINVAL"
});
}
var s = getStore(data && data.teamId);
if (!s.rpc) {
return void cb({
error: "RPC_NOT_READY"
});
}
if (typeof cb !== "function") {
console.error("expected a callback");
cb = function() {};
}
var pads = data.pads || data;
s.rpc.pin(pads, (function(e) {
if (e) {
return void cb({
error: e
});
}
cb({});
}));
};
Store.unpinPads = function(clientId, data, cb) {
if (!data) {
return void cb({
error: "EINVAL"
});
}
var s = getStore(data && data.teamId);
if (!s.rpc) {
return void cb({
error: "RPC_NOT_READY"
});
}
var pads = data.pads || data;
s.rpc.unpin(pads, (function(e) {
if (e) {
return void cb({
error: e
});
}
cb({});
}));
};
var account = store.account = {};
Store.getPinnedUsage = function(clientId, data, cb) {
var s = getStore(data && data.teamId);
if (!s || !s.rpc) {
return void cb({
error: "RPC_NOT_READY"
});
}
s.rpc.getFileListSize((function(err, bytes) {
if (!s.id && typeof bytes === "number") {
account.usage = bytes;
}
cb({
bytes
});
}));
};
Store.updatePinLimit = function(clientId, data, cb) {
if (!store.rpc) {
return void cb({
error: "RPC_NOT_READY"
});
}
store.rpc.updatePinLimits((function(e, limit, plan, note) {
if (e) {
return void cb({
error: e
});
}
account.limit = limit;
account.plan = plan;
account.note = note;
cb(account);
}));
};
Store.getPinLimit = function(clientId, data, cb) {
var s = getStore(data && data.teamId);
if (!s.rpc) {
return void cb({
error: "RPC_NOT_READY"
});
}
{
return void s.rpc.getLimit((function(e, limit, plan, note) {
if (e) {
return void cb({
error: e
});
}
var data = s.id ? {} : account;
data.limit = limit;
data.plan = plan;
data.note = note;
cb(data);
}));
}
};
Store.clearOwnedChannel = function(clientId, data, cb) {
var s = getStore(data && data.teamId);
if (!s.rpc) {
return void cb({
error: "RPC_NOT_READY"
});
}
s.rpc.clearOwnedChannel(data.channel, (function(err) {
cb({
error: err
});
}));
};
var myDeletions = {};
Store.removeOwnedChannel = function(clientId, data, cb) {
var channel = data;
var force = false;
var teamId;
var reason;
if (data && typeof data === "object") {
channel = data.channel;
force = data.force;
teamId = data.teamId;
reason = data.reason;
}
if (channel === store.driveChannel && !force) {
return void cb({
error: "User drive removal blocked!"
});
}
var s = getStore(teamId);
if (!s) {
return void cb({
error: "ENOTFOUND"
});
}
if (!s.rpc) {
return void cb({
error: "RPC_NOT_READY"
});
}
if (Store.channels[channel]) {
myDeletions[channel] = true;
}
s.rpc.removeOwnedChannel(channel, (function(err) {
if (err) {
delete myDeletions[channel];
}
cb({
error: err
});
}), reason);
};
var arePinsSynced = function(cb) {
if (!store.rpc) {
return void cb({
error: "RPC_NOT_READY"
});
}
var list = getCanonicalChannelList(false);
var local = Hash.hashChannelList(list);
store.rpc.getServerHash((function(e, hash) {
if (e) {
return void cb(e);
}
cb(null, hash === local);
}));
};
var resetPins = function(cb) {
if (!store.rpc) {
return void cb({
error: "RPC_NOT_READY"
});
}
var list = getCanonicalChannelList(false);
store.rpc.reset(list, (function(e) {
if (e) {
return void cb(e);
}
cb(null);
}));
};
Store.uploadComplete = function(clientId, data, cb) {
var s = getStore(data.teamId);
if (!s) {
return void cb({
error: "ENOTFOUND"
});
}
if (!s.rpc) {
return void cb({
error: "RPC_NOT_READY"
});
}
if (data.owned) {
s.rpc.ownedUploadComplete(data.id, (function(err, res) {
if (err) {
return void cb({
error: err
});
}
cb(res);
}));
return;
}
s.rpc.uploadComplete(data.id, (function(err, res) {
if (err) {
return void cb({
error: err
});
}
cb(res);
}));
};
Store.uploadStatus = function(clientId, data, cb) {
var s = getStore(data.teamId);
if (!s) {
return void cb({
error: "ENOTFOUND"
});
}
if (!s.rpc) {
return void cb({
error: "RPC_NOT_READY"
});
}
s.rpc.uploadStatus(data.size, (function(err, res) {
if (err) {
return void cb({
error: err
});
}
cb(res);
}));
};
Store.uploadCancel = function(clientId, data, cb) {
var s = getStore(data.teamId);
if (!s) {
return void cb({
error: "ENOTFOUND"
});
}
if (!s.rpc) {
return void cb({
error: "RPC_NOT_READY"
});
}
s.rpc.uploadCancel(data.size, (function(err, res) {
if (err) {
return void cb({
error: err
});
}
cb(res);
}));
};
Store.uploadChunk = function(clientId, data, cb) {
var s = getStore(data.teamId);
if (!s) {
return void cb({
error: "ENOTFOUND"
});
}
if (!s.rpc) {
return void cb({
error: "RPC_NOT_READY"
});
}
s.rpc.send.unauthenticated("UPLOAD", data.chunk, (function(e, msg) {
cb({
error: e,
msg
});
}));
};
var initTempRpc = (clientId, cb) => {
if (store.rpc) {
return void cb(store.rpc);
}
var kp = Crypto.Nacl.sign.keyPair();
var keys = {
edPublic: Crypto.Nacl.util.encodeBase64(kp.publicKey),
edPrivate: Crypto.Nacl.util.encodeBase64(kp.secretKey)
};
Pinpad.create(store.network, keys, (function(e, call) {
if (e) {
return void cb({
error: e
});
}
store.rpc = call;
cb(call);
}));
};
var initRpc = function(clientId, data, cb) {
if (!store.loggedIn) {
return cb();
}
if (store.rpc) {
return void cb(account);
}
Pinpad.create(store.network, store.proxy, (function(e, call) {
if (e) {
return void cb({
error: e
});
}
store.rpc = call;
store.onRpcReadyEvt.fire();
Store.getPinLimit(null, null, (function(obj) {
if (obj.error) {
console.error(obj.error);
}
account.limit = obj.limit;
account.plan = obj.plan;
account.note = obj.note;
cb(obj);
}));
}), Cache);
};
Store.anonRpcMsg = function(clientId, data, cb) {
if (!store.anon_rpc) {
return void cb({
error: "ANON_RPC_NOT_READY"
});
}
store.anon_rpc.send(data.msg, data.data, (function(err, res) {
if (err) {
return void cb({
error: err
});
}
cb(res);
}));
};
Store.getFileSize = function(clientId, data, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
if (!store.anon_rpc) {
return void cb({
error: "ANON_RPC_NOT_READY"
});
}
var channelId = data.channel || Hash.hrefToHexChannelId(data.href, data.password);
store.anon_rpc.send("GET_FILE_SIZE", channelId, (function(e, response) {
if (e) {
return void cb({
error: e
});
}
if (response && response.length && typeof response[0] === "number") {
if (response[0] === 0) {
Cache.clearChannel(channelId);
}
return void cb({
size: response[0]
});
} else {
cb({
error: "INVALID_RESPONSE"
});
}
}));
};
Store.isNewChannel = function(clientId, data, cb) {
if (!store.anon_rpc) {
return void cb({
error: "ANON_RPC_NOT_READY"
});
}
var channelId = data.channel || Hash.hrefToHexChannelId(data.href, data.password);
store.anon_rpc.send("IS_NEW_CHANNEL", channelId, (function(e, response) {
if (e) {
return void cb({
error: e
});
}
if (response && response.length && typeof response[0] === "object") {
if (response[0].isNew) {
Cache.clearChannel(channelId);
}
return void cb(response[0]);
} else {
cb({
error: "INVALID_RESPONSE"
});
}
}));
};
Store.getMultipleFileSize = function(clientId, data, cb) {
if (!store.anon_rpc) {
return void cb({
error: "ANON_RPC_NOT_READY"
});
}
if (!Array.isArray(data.files)) {
return void cb({
error: "INVALID_FILE_LIST"
});
}
store.anon_rpc.send("GET_MULTIPLE_FILE_SIZE", data.files, (function(e, res) {
if (e) {
return void cb({
error: e
});
}
if (res && res.length && typeof res[0] === "object") {
cb({
size: res[0]
});
} else {
cb({
error: "UNEXPECTED_RESPONSE"
});
}
}));
};
Store.getDeletedPads = function(clientId, data, cb) {
if (!store.anon_rpc) {
return void cb({
error: "ANON_RPC_NOT_READY"
});
}
var list = data && data.list || getCanonicalChannelList(true);
if (!Array.isArray(list)) {
return void cb({
error: "INVALID_FILE_LIST"
});
}
store.anon_rpc.send("GET_DELETED_PADS", list, (function(e, res) {
if (e) {
return void cb({
error: e
});
}
if (res && res.length && Array.isArray(res[0])) {
cb(res[0]);
} else {
cb({
error: "UNEXPECTED_RESPONSE"
});
}
}));
};
var initAnonRpc = function(clientId, data, cb) {
if (store.anon_rpc) {
return void cb();
}
Rpc.createAnonymous(store.network, (function(e, call) {
if (e) {
return void cb({
error: e
});
}
store.anon_rpc = call;
cb();
}));
};
var getAllStores = Store.getAllStores = function() {
if (!store.proxy || !store.manager) {
return [];
}
var stores = [ store ];
var teamModule = store.modules["team"];
if (teamModule) {
var teams = teamModule.getTeams().map((function(id) {
return teamModule.getTeam(id);
}));
Array.prototype.push.apply(stores, teams);
}
return stores;
};
Store.getUserColor = function() {
var color = Util.find(store, [ "proxy", "settings", "general", "cursor", "color" ]);
if (!color) {
color = Util.getRandomColor(true);
Store.setAttribute(null, {
attr: [ "general", "cursor", "color" ],
value: color
}, (function() {}));
}
return color;
};
Store.getMetadata = function(clientId, app, cb) {
var proxy = store.proxy || {};
var disableThumbnails = Util.find(proxy, [ "settings", "general", "disableThumbnails" ]);
var teams = store.modules["team"] && store.modules["team"].getTeamsData(app) || {};
if (!proxy.uid) {
store.noDriveUid = store.noDriveUid || Hash.createChannelId();
}
var metadata = {
user: {
name: proxy[Constants.displayNameKey] || store.noDriveName || "",
uid: proxy.uid || store.noDriveUid,
avatar: Util.find(proxy, [ "profile", "avatar" ]),
profile: Util.find(proxy, [ "profile", "view" ]),
color: Store.getUserColor(),
notifications: Util.find(proxy, [ "mailboxes", "notifications", "channel" ]),
curvePublic: proxy.curvePublic
},
priv: {
clientId,
edPublic: proxy.edPublic,
friends: proxy.friends || {},
settings: proxy.settings || NEW_USER_SETTINGS,
thumbnails: disableThumbnails === false,
isDriveOwned: Boolean(Util.find(store, [ "driveMetadata", "owners" ])),
driveChannel: store.driveChannel,
pendingFriends: proxy.friends_pending || {},
supportPrivateKey: Util.find(proxy, [ "mailboxes", "supportadmin", "keys", "curvePrivate" ]),
accountName: proxy.login_name || "",
offline: store.proxy && store.offline,
teams,
plan: store.ready ? account.plan || "" : undefined,
mutedChannels: proxy.mutedChannels
}
};
cb(JSON.parse(JSON.stringify(metadata)));
return metadata;
};
Store.onMaintenanceUpdate = function() {
let origin = ApiConfig.httpUnsafeOrigin;
Util.fetchApi(origin, "broadcast", true, (Broadcast => {
if (!Broadcast) {
return;
}
broadcast([], "UNIVERSAL_EVENT", {
type: "broadcast",
data: {
ev: "MAINTENANCE",
data: Broadcast.maintenance
}
});
}));
};
Store.onSurveyUpdate = function() {
let origin = ApiConfig.httpUnsafeOrigin;
Util.fetchApi(origin, "broadcast", true, (Broadcast => {
broadcast([], "UNIVERSAL_EVENT", {
type: "broadcast",
data: {
ev: "SURVEY",
data: Broadcast.surveyURL
}
});
}));
};
var makePad = function(href, roHref, title) {
var now = +new Date;
return {
href,
roHref,
atime: now,
ctime: now,
title: title || UserObject.getDefaultName(Hash.parsePadUrl(href))
};
};
Store.addPad = function(clientId, data, cb) {
if (!data.href && !data.roHref) {
return void cb({
error: "NO_HREF"
});
}
var secret;
if (!data.roHref) {
var parsed = Hash.parsePadUrl(data.href);
if (parsed.hashData.type === "pad") {
secret = Hash.getSecrets(parsed.type, parsed.hash, data.password);
data.roHref = "/" + parsed.type + "/#" + Hash.getViewHashFromKeys(secret);
}
}
var pad = makePad(data.href, data.roHref, data.title);
if (data.owners) {
pad.owners = data.owners;
}
if (data.expire) {
pad.expire = data.expire;
}
if (data.password) {
pad.password = data.password;
}
if (data.channel || secret) {
pad.channel = data.channel || secret.channel;
}
if (data.readme) {
pad.readme = 1;
}
if (data.teamId === -1) {
data.teamId = undefined;
}
var s = getStore(data.teamId);
if (!s || !s.manager) {
return void cb({
error: "ENOTFOUND"
});
}
s.manager.addPad(data.path, pad, (function(e) {
if (e) {
return void cb({
error: e
});
}
getAllStores().forEach((function(_s) {
var send = _s.id ? _s.sendEvent : sendDriveEvent;
send("DRIVE_CHANGE", {
path: [ "drive", UserObject.FILES_DATA ]
}, clientId);
}));
onSync(data.teamId, cb);
}));
};
var getOwnedPads = function(account) {
var list = [];
if (account) {
if (store.proxy.todo) {
list.push(Hash.hrefToHexChannelId("/todo/#" + store.proxy.todo, null));
}
if (store.proxy.profile && store.proxy.profile.edit) {
list.push(Hash.hrefToHexChannelId("/profile/#" + store.proxy.profile.edit, null));
}
if (store.proxy.mailboxes) {
Object.keys(store.proxy.mailboxes || {}).forEach((function(id) {
if (id === "supportadmin") {
return;
}
var m = store.proxy.mailboxes[id];
list.push(m.channel);
}));
}
} else {
list = store.manager.getChannelsList("owned");
}
return list.filter((function(channel) {
if (typeof channel !== "string") {
return;
}
return [ 32, 48 ].indexOf(channel.length) !== -1;
}));
};
var removeOwnedPads = function(account, waitFor) {
var edPublic = Util.find(store, [ "proxy", "edPublic" ]);
var ownedPads = getOwnedPads(account);
var sem = Saferphore.create(10);
var deleteChannel = function(c) {
if (account) {
return;
}
var all = store.manager.findChannel(c);
all.forEach((function(d) {
var p = store.manager.findFile(d.id);
store.manager.delete({
paths: p
});
}));
};
ownedPads.forEach((function(c) {
var w = waitFor();
sem.take((function(give) {
var otherOwners = false;
nThen((function(_w) {
if (c.length !== 32) {
return;
}
Store.anonRpcMsg(null, {
msg: "GET_METADATA",
data: c
}, _w((function(obj) {
if (obj && obj.error) {
give();
w();
return void _w.abort();
}
var md = obj[0];
if (!Object.keys(md || {}).length) {
deleteChannel(c);
give();
w();
return void _w.abort();
}
var isOwner = md && Array.isArray(md.owners) && md.owners.indexOf(edPublic) !== -1;
if (!isOwner) {
give();
w();
return void _w.abort();
}
otherOwners = md.owners.some((function(ed) {
return ed !== edPublic;
}));
})));
})).nThen((function(_w) {
if (otherOwners) {
Store.setPadMetadata(null, {
channel: c,
command: "RM_OWNERS",
value: [ edPublic ]
}, _w());
return;
}
store.rpc.removeOwnedChannel(c, _w((function(err) {
if (err) {
return void console.error(err);
}
deleteChannel(c);
})));
})).nThen((function() {
give();
w();
}));
}));
}));
};
Store.removeOwnedPads = function(clientId, data, cb) {
var edPublic = store.proxy.edPublic;
if (!edPublic) {
return void cb({
error: "NOT_LOGGED_IN"
});
}
nThen((function(waitFor) {
removeOwnedPads(false, waitFor);
})).nThen(cb);
};
Store.deleteAccount = function(clientId, data, cb) {
var edPublic = store.proxy.edPublic;
var blockKeys = data && data.keys;
var auth = data && data.auth;
Store.anonRpcMsg(clientId, {
msg: "GET_METADATA",
data: store.driveChannel
}, (function(data) {
var metadata = data[0];
if (metadata && metadata.owners && metadata.owners.length === 1 && metadata.owners.indexOf(edPublic) !== -1) {
nThen((function(waitFor) {
Block.checkRights({
auth,
blockKeys
}, waitFor((function(err) {
if (err) {
waitFor.abort();
console.error(err);
return void cb({
error: "INVALID_CODE"
});
}
})));
})).nThen((function(waitFor) {
globalThis.accountDeletion = clientId;
store.proxy[Constants.tokenKey] = "DELETED";
onSync(null, waitFor());
})).nThen((function(waitFor) {
store.rpc.removePins(waitFor((function(err) {
if (err) {
console.error(err);
}
})));
})).nThen((function(waitFor) {
store.ownDeletion = true;
Store.removeOwnedChannel(clientId, {
channel: store.driveChannel,
force: true
}, waitFor());
})).nThen((function(waitFor) {
if (!blockKeys) {
return;
}
Block.removeLoginBlock({
reason: "ARCHIVE_OWNED",
auth,
edPublic,
blockKeys
}, waitFor((function(err) {
if (err) {
console.error(err);
}
})));
})).nThen((function(waitFor) {
removeOwnedPads(true, waitFor);
})).nThen((function() {
broadcast([ clientId ], "DRIVE_DELETED", "ARCHIVE_OWNED");
postMessage(clientId, "DELETE_ACCOUNT", "DELETED", (function() {}));
store.network.disconnect();
cb({
state: true
});
}));
return;
}
var toSign = {
intent: "Please delete my account."
};
toSign.drive = store.driveChannel;
toSign.edPublic = edPublic;
var signKey = Crypto.Nacl.util.decodeBase64(store.proxy.edPrivate);
var proof = Crypto.Nacl.sign.detached(Crypto.Nacl.util.decodeUTF8(Sortify(toSign)), signKey);
var check = Crypto.Nacl.sign.detached.verify(Crypto.Nacl.util.decodeUTF8(Sortify(toSign)), proof, Crypto.Nacl.util.decodeBase64(edPublic));
if (!check) {
console.error("signed message failed verification");
}
var proofTxt = Crypto.Nacl.util.encodeBase64(proof);
cb({
proof: proofTxt,
toSign: JSON.parse(Sortify(toSign))
});
}));
};
Store.migrateAnonDrive = function(clientId, data, cb) {
var hash = data.anonHash;
Merge.anonDriveIntoUser(store, hash, cb);
};
Store.setDisplayName = function(clientId, value, cb) {
if (!store.proxy) {
store.noDriveName = value;
broadcast([ clientId ], "UPDATE_METADATA");
return void cb();
}
if (store.modules["profile"]) {
store.modules["profile"].setName(value);
}
store.proxy[Constants.displayNameKey] = value;
broadcast([ clientId ], "UPDATE_METADATA");
Messaging.updateMyData(store);
onSync(null, cb);
};
Store.resetDrive = function(clientId, data, cb) {
nThen((function(waitFor) {
removeOwnedPads(waitFor);
})).nThen((function() {
store.proxy.drive = store.userObject.getStructure();
sendDriveEvent("DRIVE_CHANGE", {
path: [ "drive", "filesData" ]
}, clientId);
onSync(null, cb);
}));
};
Store.setPadAttribute = function(clientId, data, cb) {
nThen((function(waitFor) {
getAllStores().forEach((function(s) {
s.manager.setPadAttribute(data, waitFor((function() {
var send = s.id ? s.sendEvent : sendDriveEvent;
send("DRIVE_CHANGE", {
path: [ "drive", UserObject.FILES_DATA ]
}, clientId);
onSync(s.id, waitFor());
})));
}));
})).nThen(cb);
};
Store.getPadAttribute = function(clientId, data, cb) {
var res = {};
nThen((function(waitFor) {
getAllStores().forEach((function(s) {
s.manager.getPadAttribute(data, waitFor((function(err, val) {
if (err) {
return;
}
if (!val || typeof val !== "object") {
return void console.error("Not an object!");
}
if (!res.value || res.atime < val.atime) {
res.atime = val.atime;
res.value = val.value;
}
})));
}));
})).nThen((function() {
cb(res.value);
}));
};
var getAttributeObject = function(attr) {
if (typeof attr === "string") {
console.error("DEPRECATED: use setAttribute with an array, not a string");
return {
path: [ "settings" ],
obj: store.proxy.settings,
key: attr
};
}
if (!Array.isArray(attr)) {
return void console.error("Attribute must be string or array");
}
if (attr.length === 0) {
return void console.error("Attribute can't be empty");
}
var obj = store.proxy.settings;
attr.forEach((function(el, i) {
if (i === attr.length - 1) {
return;
}
if (!obj[el]) {
obj[el] = {};
} else if (typeof obj[el] !== "object") {
return void console.error("Wrong attribute");
}
obj = obj[el];
}));
return {
path: [ "settings" ].concat(attr),
obj,
key: attr[attr.length - 1]
};
};
Store.setAttribute = function(clientId, data, cb) {
try {
var object = getAttributeObject(data.attr);
object.obj[object.key] = data.value;
} catch (e) {
return void cb({
error: e
});
}
onSync(null, (function() {
cb();
broadcast([], "UPDATE_METADATA");
}));
};
Store.getAttribute = function(clientId, data, cb) {
var object;
try {
object = getAttributeObject(data.attr);
} catch (e) {
return void cb({
error: e
});
}
cb(object.obj[object.key]);
};
Store.listAllTags = function(clientId, data, cb) {
var tags = {};
getAllStores().forEach((function(s) {
var l = s.manager.getTagsList();
Object.keys(l).forEach((function(tag) {
tags[tag] = (tags[tag] || 0) + l[tag];
}));
}));
cb(tags);
};
Store.getTemplates = function(clientId, data, cb) {
var res = [];
var channels = [];
getAllStores().forEach((function(s) {
var templateFiles = s.userObject.getFiles([ "template" ]);
templateFiles.forEach((function(f) {
var data = s.userObject.getFileData(f);
if (channels.indexOf(data.channel) !== -1) {
return;
}
channels.push(data.channel);
res.push(JSON.parse(JSON.stringify(data)));
}));
}));
cb(res);
};
Store.incrementTemplateUse = function(clientId, href) {
getAllStores().forEach((function(s) {
s.userObject.getPadAttribute(href, "used", (function(err, data) {
if (err) {
return;
}
var used = typeof data === "number" ? ++data : 1;
s.userObject.setPadAttribute(href, "used", used);
}));
}));
};
Store.isOnlyInSharedFolder = function(clientId, channel, cb) {
var res = false;
var isInMainDrive = function(obj) {
return !obj.fId;
};
getAllStores().some((function(s) {
var _res = s.manager.findChannel(channel);
if (!_res.length) {
return;
}
if (_res.some(isInMainDrive)) {
res = false;
return true;
}
res = true;
}));
return cb(res);
};
Store.moveToTrash = function(clientId, data, cb) {
var href = Hash.getRelativeHref(data.href);
var allErrors = true;
nThen((function(waitFor) {
getAllStores().forEach((function(s) {
var deleted = s.userObject.forget(href);
if (!deleted) {
return;
}
allErrors = false;
var send = s.id ? s.sendEvent : sendDriveEvent;
send("DRIVE_CHANGE", {
path: [ "drive", UserObject.FILES_DATA ]
}, clientId);
onSync(s.id, waitFor());
}));
})).nThen((function() {
cb({
error: allErrors ? "FORBIDDEN" : undefined
});
}));
};
Store.setPadTitle = function(clientId, data, cb) {
onReadyEvt.reg((function() {
var title = data.title;
var href = data.href;
var channel = data.channel;
var p = Hash.parsePadUrl(href);
var h = p.hashData;
if (title.trim() === "") {
title = UserObject.getDefaultName(p);
}
if (AppConfig.disableAnonymousStore && !store.loggedIn) {
return void cb({
notStored: true
});
}
if (p.type === "debug") {
return void cb({
notStored: true
});
}
var channelData = Store.channels && Store.channels[channel];
var owners;
if (channelData && channelData.wc && channel === channelData.wc.id) {
owners = channelData.data.owners || undefined;
}
if (data.owners) {
owners = data.owners;
}
var expire;
if (channelData && channelData.wc && channel === channelData.wc.id) {
expire = +channelData.data.expire || undefined;
}
if (data.expire) {
expire = data.expire;
}
if (data.teamId) {
data.teamId = Number(data.teamId);
}
var allData = [];
var sendTo = [];
var inTargetDrive, inMyDrive;
getAllStores().forEach((function(s) {
if (h.mode === "edit" && s.id && !s.secondaryKey) {
return;
}
var res = s.manager.findChannel(channel, true);
if (res.length) {
sendTo.push(s.id);
}
if (!s.id && (!data.teamId || data.teamId === -1) || Number(s.id) === data.teamId) {
if (!inTargetDrive) {
inTargetDrive = res.length;
}
}
if (!s.id) {
inMyDrive = res.length;
}
Array.prototype.push.apply(allData, res);
}));
var contains = allData.length !== 0;
if (store.offline && !contains) {
return void cb({
error: "OFFLINE"
});
} else if (store.offline) {
return void cb();
}
allData.forEach((function(obj) {
var pad = obj.data;
pad.atime = +new Date;
pad.title = title;
if (owners || h.type !== "file") {
pad.owners = owners;
}
pad.expire = expire;
if (pad.readme) {
delete pad.readme;
Feedback.send("OPEN_README");
}
if (h.mode === "view") {
return;
}
if (!pad.href) {
obj.userObject.restoreHref(href);
}
obj.userObject.setHref(channel, null, href);
}));
if (!contains || data.forceSave && !inTargetDrive) {
var autoStore = Util.find(store.proxy, [ "settings", "general", "autostore" ]);
if (autoStore !== 1 && !data.forceSave && !data.path) {
postMessage(clientId, "AUTOSTORE_DISPLAY_POPUP", {
autoStore
});
return void cb({
notStored: true
});
} else {
var roHref;
if (h.mode === "view") {
roHref = href;
href = undefined;
}
Store.addPad(clientId, {
teamId: data.teamId,
href,
roHref,
channel,
title,
owners,
expire,
password: data.password,
path: data.path
}, cb);
postMessage(clientId, "AUTOSTORE_DISPLAY_POPUP", {
stored: true,
inMyDrive: inMyDrive || !contains && !data.teamId
});
return;
}
}
sendTo.forEach((function(teamId) {
var send = teamId ? getStore(teamId).sendEvent : sendDriveEvent;
send("DRIVE_CHANGE", {
path: [ "drive", UserObject.FILES_DATA ]
}, clientId);
}));
postMessage(clientId, "AUTOSTORE_DISPLAY_POPUP", {
stored: true,
inMyDrive
});
nThen((function(waitFor) {
sendTo.forEach((function(teamId) {
onSync(teamId, waitFor());
}));
})).nThen(cb);
}));
};
Store.getSecureFilesList = function(clientId, query, cb) {
var list = {};
var types = query.types;
var where = query.where;
var filter = query.filter || {};
var isFiltered = function(type, data) {
var filtered;
var fType = filter.fileType || [];
if (type === "file" && fType.length) {
if (!data.fileType) {
return true;
}
filtered = !fType.some((function(t) {
return data.fileType.indexOf(t) === 0;
}));
}
return filtered;
};
var channels = [];
getAllStores().forEach((function(s) {
s.manager.getSecureFilesList(where).forEach((function(obj) {
var data = obj.data;
if (channels.indexOf(data.channel || data.id) !== -1) {
return;
}
var id = obj.id;
if (data.channel) {
channels.push(data.channel || data.id);
}
if (data.static) {
if (types.indexOf("link") !== -1) {
list[id] = data;
}
return;
}
var parsed = Hash.parsePadUrl(data.href || data.roHref);
if ((!types || types.length === 0 || types.indexOf(parsed.type) !== -1) && !isFiltered(parsed.type, data)) {
list[id] = data;
}
}));
}));
cb(list);
};
Store.getPadData = function(clientId, id, cb) {
var res = {};
getAllStores().some((function(s) {
var d = s.userObject.getFileData(id);
if (!d.roHref && !d.href) {
return;
}
res = d;
return true;
}));
cb(res);
};
Store.getPadDataFromChannel = function(clientId, obj, cb) {
var channel = obj.channel;
var edit = obj.edit;
var isFile = obj.file;
var res;
var viewRes;
getAllStores().some((function(s) {
var chans = s.manager.findChannel(channel);
if (!Array.isArray(chans)) {
return;
}
return chans.some((function(pad) {
if (!pad || !pad.data) {
return;
}
var data = pad.data;
if (edit && data.href || !edit && data.roHref || isFile) {
res = data;
return true;
}
if (edit && !viewRes && data.roHref) {
viewRes = data;
}
}));
}));
var result = res || viewRes;
if (!result && store.offline) {
onReadyEvt.reg((function() {
Store.getPadDataFromChannel(clientId, obj, cb);
}));
return;
}
cb(result || {});
};
Store.checkDeletedPad = function(channel, cb) {
if (!channel) {
return;
}
Store.getPadDataFromChannel(null, {
channel,
isFile: true
}, (function(res) {
if (typeof cb === "function") {
setTimeout(cb);
}
if (Object.keys(res).length) {
return;
}
broadcast([], "CHANNEL_DELETED", channel);
}));
};
Store.answerFriendRequest = function(clientId, obj, cb) {
var value = obj.value;
var data = obj.data;
if (data.type !== "notifications") {
return void cb({
error: "EINVAL"
});
}
var hash = data.content.hash;
var msg = data.content.msg;
var dismiss = function(cb) {
cb = cb || function() {};
store.mailbox.dismiss({
hash,
type: "notifications"
}, cb);
};
if (value) {
Messaging.acceptFriendRequest(store, msg.content.user, (function(obj) {
if (obj && obj.error) {
return void cb(obj);
}
Messaging.addToFriendList({
proxy: store.proxy,
realtime: store.realtime,
pinPads: function(data, cb) {
Store.pinPads(null, data, cb);
}
}, msg.content.user, (function(err) {
if (store.messenger) {
store.messenger.onFriendAdded(msg.content.user);
}
broadcast([], "UPDATE_METADATA");
if (err) {
return void cb({
error: err
});
}
dismiss(cb);
}));
}));
return;
}
Messaging.declineFriendRequest(store, msg.content.user, (function(obj) {
broadcast([], "UPDATE_METADATA");
cb(obj);
}));
dismiss();
};
Store.sendFriendRequest = function(clientId, data, cb) {
var friend = Messaging.getFriend(store.proxy, data.curvePublic);
if (friend) {
return void cb({
error: "ALREADY_FRIEND"
});
}
if (!data.notifications || !data.curvePublic) {
return void cb({
error: "INVALID_USER"
});
}
store.proxy.friends_pending = store.proxy.friends_pending || {};
var p = store.proxy.friends_pending[data.curvePublic];
if (p) {
return void cb({
error: "ALREADY_SENT"
});
}
store.proxy.friends_pending[data.curvePublic] = {
time: +new Date,
channel: data.notifications,
curvePublic: data.curvePublic
};
broadcast([], "UPDATE_METADATA");
store.mailbox.sendTo("FRIEND_REQUEST", {
user: Messaging.createData(store.proxy)
}, {
channel: data.notifications,
curvePublic: data.curvePublic
}, (function(obj) {
cb(obj);
}));
};
Store.cancelFriendRequest = function(data, cb) {
if (!data.curvePublic || !data.notifications) {
return void cb({
error: "EINVAL"
});
}
var proxy = store.proxy;
var f = Messaging.getFriend(proxy, data.curvePublic);
if (f) {
console.error("You can't cancel an accepted friend request");
return void cb({
error: "ALREADY_FRIEND"
});
}
var pending = Util.find(store, [ "proxy", "friends_pending" ]) || {};
if (!pending) {
return void cb();
}
store.mailbox.sendTo("CANCEL_FRIEND_REQUEST", {
user: Messaging.createData(store.proxy)
}, {
channel: data.notifications,
curvePublic: data.curvePublic
}, (function(obj) {
if (obj && obj.error) {
return void cb(obj);
}
delete store.proxy.friends_pending[data.curvePublic];
broadcast([], "UPDATE_METADATA");
onSync(null, (function() {
cb(obj);
}));
}));
};
Store.anonGetPreviewContent = function(clientId, data, cb) {
Team.anonGetPreviewContent({
store
}, data, cb);
};
Store.getStrongerHash = function(clientId, data, _cb) {
var cb = Util.once(_cb);
var found = getAllStores().some((function(s) {
var stronger = s.manager.getEditHash(data.channel);
if (stronger) {
cb(stronger);
return true;
}
}));
if (!found) {
cb();
}
};
Store.universal = {
execCommand: function(clientId, obj, cb) {
var todo = function() {
var type = obj.type;
var data = obj.data;
if (store.modules[type]) {
store.modules[type].execCommand(clientId, data, cb);
} else {
return void cb({
error: type + " is disabled"
});
}
};
if ([ "team", "calendar" ].indexOf(obj.type) !== -1) {
return void todo();
}
if (!store.proxy) {
return void todo();
}
onReadyEvt.reg(todo);
}
};
var loadUniversal = function(Module, type, waitFor, clientId) {
if (store.modules[type]) {
return;
}
store.modules[type] = Module.init({
Store,
store,
updateLoadingProgress: function(data) {
data.type = "team";
postMessage(clientId, "LOADING_DRIVE", data);
},
updateMetadata: function() {
broadcast([], "UPDATE_METADATA");
},
pinPads: function(data, cb) {
Store.pinPads(null, data, cb);
},
unpinPads: function(data, cb) {
Store.unpinPads(null, data, cb);
}
}, waitFor, (function(ev, data, clients) {
clients.forEach((function(cId) {
postMessage(cId, "UNIVERSAL_EVENT", {
type,
data: {
ev,
data
}
});
}));
}));
};
Store.onlyoffice = {
execCommand: function(clientId, data, cb) {
if (!store.onlyoffice) {
return void cb({
error: "OnlyOffice is disabled"
});
}
store.onlyoffice.execCommand(clientId, data, cb);
}
};
Store.mailbox = {
execCommand: function(clientId, data, cb) {
onReadyEvt.reg((function() {
if (!store.mailbox) {
return void cb({
error: "Mailbox is disabled"
});
}
store.mailbox.execCommand(clientId, data, cb);
}));
}
};
Store.adminRpc = function(clientId, data, cb) {
store.rpc.adminRpc(data, (function(err, res) {
if (err) {
return void cb({
error: err
});
}
cb(res);
}));
};
Store.addAdminMailbox = function(clientId, data, cb) {
var priv = data && data.priv;
var pub = Hash.getBoxPublicFromSecret(priv);
var isNewSupport = data && data.version === 2;
if (!priv || !pub) {
return void cb({
error: "EINVAL"
});
}
var channel = Hash.getChannelIdFromKey(pub);
var mailboxes = store.proxy.mailboxes = store.proxy.mailboxes || {};
var key = isNewSupport ? "supportteam" : "supportadmin";
var box = mailboxes[key] = {
channel,
viewed: [],
lastKnownHash: data.lastKnownHash || "",
keys: {
curvePublic: pub,
curvePrivate: priv
}
};
Store.pinPads(null, [ channel ], (function() {}));
store.mailbox.open(key, box, (function() {
console.log("ready");
}));
onSync(null, cb);
};
var channels = Store.channels = store.channels = {};
Store.getSnapshot = function(clientId, data, cb) {
Store.getHistoryRange(clientId, {
cpCount: 1,
channel: data.channel,
lastKnownHash: data.hash
}, cb);
};
var getVersionHash = function(clientId, data) {
var validateKey;
var fakeNetflux = Hash.createChannelId();
nThen((function(waitFor) {
Store.getPadMetadata(null, {
channel: data.channel
}, waitFor((function(md) {
if (md && md.rejected) {
postMessage(clientId, "PAD_ERROR", {
type: "ERESTRICTED"
});
waitFor.abort();
return;
}
validateKey = md.validateKey;
})));
})).nThen((function() {
Store.getHistoryRange(clientId, {
cpCount: 1,
channel: data.channel,
lastKnownHash: data.versionHash
}, (function(obj) {
if (obj && obj.error) {
postMessage(clientId, "PAD_ERROR", obj.error);
return;
}
var msgs = obj.messages || [];
if (msgs.length && msgs[msgs.length - 1].serverHash !== data.versionHash) {
postMessage(clientId, "PAD_ERROR", {
type: "HASH_NOT_FOUND"
});
return;
}
postMessage(clientId, "PAD_CONNECT", {
myID: fakeNetflux,
id: data.channel,
members: [ fakeNetflux ]
});
(obj.messages || []).forEach((function(data) {
postMessage(clientId, "PAD_MESSAGE", {
msg: data.msg,
time: data.time,
user: fakeNetflux.slice(0, 16)
});
}));
if (validateKey && store.messenger) {
store.messenger.storeValidateKey(data.channel, validateKey);
}
postMessage(clientId, "PAD_READY");
}));
}));
};
Store.onRejected = function(allowed, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
if (!Array.isArray(allowed)) {
return void cb("ERESTRICTED");
}
onPadRejectedEvt.fire();
onReadyEvt.reg((() => {
if (!store.loggedIn || !store.proxy.edPublic) {
return void cb("ERESTRICTED");
}
var teamModule = store.modules["team"];
var teams = teamModule && teamModule.getTeams() || [];
var _store;
if (allowed.indexOf(store.proxy.edPublic) !== -1) {
_store = store;
} else if (teams.some((function(teamId) {
var ed = Util.find(store, [ "proxy", "teams", teamId, "keys", "drive", "edPublic" ]);
var edPrivate = Util.find(store, [ "proxy", "teams", teamId, "keys", "drive", "edPrivate" ]);
if (allowed.indexOf(ed) === -1) {
return false;
}
if (!edPrivate) {
return false;
}
var t = teamModule.getTeam(teamId);
_store = t;
return true;
}))) ;
var auth = function() {
if (!_store) {
return void cb("ERESTRICTED");
}
var rpc = _store.rpc;
if (!rpc) {
return void cb("ERESTRICTED");
}
rpc.send("COOKIE", "", (function(err) {
cb(err);
}));
};
if (_store && _store.onRpcReadyEvt) {
_store.onRpcReadyEvt.reg((function() {
auth();
}));
return;
}
auth();
}));
};
Store.joinPad = function(clientId, data) {
if (data.versionHash) {
return void getVersionHash(clientId, data);
}
if (!Hash.isValidChannel(data.channel)) {
return void postMessage(clientId, "PAD_ERROR", "INVALID_CHAN");
}
var isNew = typeof channels[data.channel] === "undefined";
var channel = channels[data.channel] = channels[data.channel] || {
queue: [],
data: {},
clients: [],
bcast: function(cmd, data, notMe) {
channel.clients.forEach((function(cId) {
if (cId === notMe) {
return;
}
postMessage(cId, cmd, data);
}));
},
history: [],
pushHistory: function(msg, isCp) {
if (isCp) {
channel.history.push("cp|" + msg);
var i;
for (i = channel.history.length - 101; i > 0; i--) {
if (/^cp\|/.test(channel.history[i])) {
break;
}
}
channel.history = channel.history.slice(Math.max(i, 0));
return;
}
channel.history.push(msg);
}
};
if (channel.clients.indexOf(clientId) === -1) {
channel.clients.push(clientId);
}
if (!isNew && channel.wc) {
postMessage(clientId, "PAD_CONNECT", {
myID: channel.wc.myID,
id: channel.wc.id,
members: channel.wc.members
});
channel.wc.members.forEach((function(m) {
postMessage(clientId, "PAD_JOIN", m);
}));
channel.history.forEach((function(msg) {
postMessage(clientId, "PAD_MESSAGE", {
msg: CpNetflux.removeCp(msg),
user: channel.wc.myID,
validateKey: channel.data.validateKey
});
}));
postMessage(clientId, "PAD_READY");
return;
}
var onError = function(err) {
if (err && err.type === "EDELETED" && myDeletions[data.channel]) {
delete myDeletions[channel];
err.ownDeletion = true;
}
channel.bcast("PAD_ERROR", err);
if (err && err.type === "EDELETED" && Cache && Cache.clearChannel) {
Cache.clearChannel(data.channel);
}
if ([ "EDELETED", "EEXPIRED", "ERESTRICTED" ].indexOf(err.type) === -1) {
return;
}
Store.leavePad(null, data, (function() {}));
};
var conf = {
Cache: store.neverCache ? undefined : Cache,
priority: 1,
onCacheStart: function() {
postMessage(clientId, "PAD_CACHE");
},
onCacheReady: function() {
console.error("PAD CACHE READY");
postMessage(clientId, "PAD_CACHE_READY");
},
onReady: function(pad) {
console.error("PAD READY");
var padData = pad.metadata || {};
channel.data = padData;
if (padData && padData.validateKey && store.messenger) {
store.messenger.storeValidateKey(data.channel, padData.validateKey);
}
postMessage(clientId, "PAD_READY", pad.noCache);
},
onMessage: function(m, user, validateKey, isCp, hash) {
channel.lastHash = hash;
channel.pushHistory(m, isCp);
channel.bcast("PAD_MESSAGE", {
user,
msg: m,
validateKey
});
},
onJoin: function(m) {
channel.bcast("PAD_JOIN", m);
},
onLeave: function(m) {
channel.bcast("PAD_LEAVE", m);
},
onError,
onChannelError: onError,
onRejected: Store.onRejected,
onConnectionChange: function(info) {
if (!info.state) {
channel.bcast("PAD_DISCONNECT");
}
},
onMetadataUpdate: function(metadata) {
channel.data = metadata || {};
getAllStores().forEach((function(s) {
var allData = s.manager.findChannel(data.channel, true);
allData.forEach((function(obj) {
obj.data.owners = metadata.owners;
obj.data.atime = +new Date;
if (metadata.expire) {
obj.data.expire = +metadata.expire;
}
}));
var send = s.sendEvent || sendDriveEvent;
send("DRIVE_CHANGE", {
path: [ "drive", UserObject.FILES_DATA ]
});
}));
channel.bcast("PAD_METADATA", metadata);
},
crypto: {
encrypt: function(m) {
return m;
},
decrypt: function(m) {
return m;
}
},
noChainPad: true,
channel: data.channel,
metadata: data.metadata,
network: store.network || store.networkPromise,
websocketURL: NetConfig.getWebsocketURL(),
onInit: function() {
onJoinedEvt.fire();
},
onConnect: function(wc, sendMessage) {
channel.sendMessage = function(msg, cId, cb) {
sendMessage(msg, (function(err) {
if (err) {
return void cb({
error: err
});
}
channel.lastHash = msg.slice(0, 64);
channel.pushHistory(CpNetflux.removeCp(msg), /^cp\|/.test(msg));
channel.bcast("PAD_MESSAGE", {
user: wc.myID,
msg: CpNetflux.removeCp(msg),
validateKey: channel.data.validateKey
}, cId);
cb();
}));
};
channel.wc = wc;
channel.queue.forEach((function(data) {
channel.sendMessage(data.message, clientId);
}));
channel.queue = [];
channel.bcast("PAD_CONNECT", {
myID: wc.myID,
id: wc.id,
members: wc.members
});
}
};
channel.cpNf = CpNetflux.start(conf);
};
Store.leavePad = function(clientId, data, cb) {
var channel = channels[data.channel];
if (!channel || !channel.cpNf) {
return void cb({
error: "EINVAL"
});
}
Store.dropChannel(data.channel);
cb();
};
Store.sendPadMsg = function(clientId, data, cb) {
var msg = data.msg;
var channel = channels[data.channel];
if (!channel) {
return;
}
if (!channel.wc) {
channel.queue.push(msg);
return void cb();
}
channel.sendMessage(msg, clientId, cb);
};
Store.corruptedCache = function(clientId, channel) {
var chan = channels[channel];
if (!chan || !chan.cpNf) {
return;
}
Cache.clearChannel(channel);
if (!chan.cpNf.resetCache) {
return;
}
chan.cpNf.resetCache();
};
Store.changePadPasswordPin = function(clientId, data, cb) {
var oldChannel = data.oldChannel;
var channel = data.channel;
nThen((function(waitFor) {
getAllStores().forEach((function(s) {
var allData = s.manager.findChannel(channel);
if (!allData.length) {
return;
}
s.rpc.unpin([ oldChannel ], waitFor());
s.rpc.pin([ channel ], waitFor());
}));
})).nThen(cb);
};
Store.contactPadOwner = function(clientId, data, cb) {
var owners = data.owners;
if (!Array.isArray(owners) || !owners.length) {
return cb({
state: false
});
}
if (!data.send) {
return void cb({
state: true
});
}
nThen((function(waitFor) {
owners.forEach((function(owner) {
var sendTo = function(query, msg, user, _cb) {
if (store.mailbox && !data.anon) {
return store.mailbox.sendTo(query, msg, user, _cb);
}
Mailbox.sendToAnon(store.anon_rpc, query, msg, user, _cb);
};
sendTo(data.query, {
channel: data.channel,
data: data.msgData
}, {
channel: owner.notifications,
curvePublic: owner.curvePublic
}, waitFor());
}));
})).nThen((function() {
cb({
state: true
});
}));
};
Store.givePadAccess = function(clientId, data, cb) {
var edPublic = store.proxy.edPublic;
var channel = data.channel;
var res = store.manager.findChannel(channel);
if (!data.user || !data.user.notifications || !data.user.curvePublic) {
return void cb({
error: "EINVAL"
});
}
var href, title;
if (!res.some((function(obj) {
if (obj.data && Array.isArray(obj.data.owners) && obj.data.owners.indexOf(edPublic) !== -1 && obj.data.href) {
href = obj.data.href;
title = obj.data.title;
return true;
}
}))) {
return void cb({
error: "ENOTFOUND"
});
}
store.mailbox.sendTo("GIVE_PAD_ACCESS", {
channel,
href,
title
}, {
channel: data.user.notifications,
curvePublic: data.user.curvePublic
});
cb();
};
Store.getLastHash = function(clientId, data, cb) {
var chan = channels[data.channel];
if (!chan) {
return void cb({
error: "ENOCHAN"
});
}
if (!chan.lastHash) {
return void cb({
error: "EINVAL"
});
}
cb({
hash: chan.lastHash
});
};
var notifyOwnerPadRemoved = function(data, obj) {
var channel = data.channel;
var href = data.href;
var parsed = Hash.parsePadUrl(href);
var secret = Hash.getSecrets(parsed.type, parsed.hash, data.password);
if (obj && obj.error) {
return;
}
if (!obj.mailbox) {
return;
}
var crypto = Crypto.createEncryptor(secret.keys);
var m = [];
try {
if (typeof obj.mailbox === "string") {
m.push(crypto.decrypt(obj.mailbox, true, true));
} else {
Object.keys(obj.mailbox).forEach((function(k) {
m.push(crypto.decrypt(obj.mailbox[k], true, true));
}));
}
} catch (e) {
console.error(e);
}
var curvePublic;
try {
curvePublic = store.proxy.curvePublic;
} catch (err) {
console.error(err);
return;
}
m.forEach((function(obj) {
var mb = JSON.parse(obj);
if (mb.curvePublic === curvePublic) {
return;
}
store.mailbox.sendTo("OWNED_PAD_REMOVED", {
channel
}, {
channel: mb.notifications,
curvePublic: mb.curvePublic
}, (function() {}));
}));
};
Store.burnPad = function(clientId, data) {
var channel = data.channel;
var ownerKey = Crypto.b64AddSlashes(data.ownerKey || "");
if (!channel || !ownerKey) {
return void console.error("Can't delete BAR pad");
}
try {
var signKey = Hash.decodeBase64(ownerKey);
var pair = Crypto.Nacl.sign.keyPair.fromSecretKey(signKey);
Pinpad.create(store.network, {
edPublic: Hash.encodeBase64(pair.publicKey),
edPrivate: Hash.encodeBase64(pair.secretKey)
}, (function(e, rpc) {
if (e) {
return void console.error(e);
}
Store.getPadMetadata(null, {
channel
}, (function(md) {
rpc.removeOwnedChannel(channel, (function(err) {
if (err) {
return void console.error(err);
}
notifyOwnerPadRemoved(data, md);
}));
}));
}));
} catch (e) {
console.error(e);
}
};
Store.getPadMetadata = function(clientId, data, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
if (store.offline || !store.anon_rpc) {
return void cb({
error: "OFFLINE"
});
}
if (!data.channel) {
return void cb({
error: "ENOTFOUND"
});
}
if (data.channel.length !== 32) {
return void cb({
error: "EINVAL"
});
}
if (!Hash.isValidChannel(data.channel)) {
Feedback.send("METADATA_INVALID_CHAN");
return void cb({
error: "EINVAL"
});
}
store.anon_rpc.send("GET_METADATA", data.channel, (function(err, obj) {
if (err) {
return void cb({
error: err
});
}
var metadata = obj && obj[0] || {};
cb(metadata);
if (metadata.rejected) {
return;
}
getAllStores().forEach((function(s) {
var allData = s.manager.findChannel(data.channel, true);
var changed = false;
allData.forEach((function(obj) {
if (Sortify(obj.data.owners) !== Sortify(metadata.owners)) {
changed = true;
}
obj.data.owners = metadata.owners;
obj.data.atime = +new Date;
if (metadata.expire) {
obj.data.expire = +metadata.expire;
}
}));
if (!changed) {
return;
}
var send = s.sendEvent || sendDriveEvent;
send("DRIVE_CHANGE", {
path: [ "drive", UserObject.FILES_DATA ]
});
}));
}));
};
Store.setPadMetadata = function(clientId, data, cb) {
if (!data.channel) {
return void cb({
error: "ENOTFOUND"
});
}
if (!data.command) {
return void cb({
error: "EINVAL"
});
}
var s = getStore(data.teamId);
if (!s) {
return void cb({
error: "ENOTFOUND"
});
}
var otherChannels = data.channels;
delete data.channels;
s.rpc.setMetadata(data, (function(err, res) {
if (err) {
return void cb({
error: err
});
}
if (!Array.isArray(res) || !res.length) {
return void cb({});
}
cb(res[0]);
}));
if (Array.isArray(otherChannels)) {
otherChannels.forEach((function(chan) {
var _d = Util.clone(data);
_d.channel = chan;
Store.setPadMetadata(clientId, _d, (function() {}));
}));
}
};
Store.deleteMailboxMessage = function(clientId, data, cb) {
if (!store.anon_rpc) {
return void cb({
error: "RPC_NOT_READY"
});
}
store.anon_rpc.send("DELETE_MAILBOX_MESSAGE", data, (function(e) {
cb({
error: e
});
}));
};
Store.getFullHistory = function(clientId, data, cb) {
var network = store.network;
var hk = network.historyKeeper;
var parse = function(msg) {
try {
return JSON.parse(msg);
} catch (e) {
return null;
}
};
var msgs = [];
var completed = false;
var onMsg = function(msg) {
if (completed) {
return;
}
var parsed = parse(msg);
if (!parsed) {
return;
}
if (parsed[0] === "FULL_HISTORY_END") {
cb(msgs);
network.off("message", onMsg);
completed = true;
return;
}
if (parsed[0] !== "FULL_HISTORY") {
return;
}
if (parsed[1] && parsed[1].validateKey) {
return;
}
if (parsed[1][3] !== data.channel) {
return;
}
msg = parsed[1][4];
if (msg) {
msg = msg.replace(/cp\|(([A-Za-z0-9+\/=]+)\|)?/, "");
if (data.debug) {
msgs.push({
serverHash: msg.slice(0, 64),
msg,
author: parsed[1][1],
time: parsed[1][5]
});
} else {
msgs.push(msg);
}
}
};
network.on("message", onMsg);
network.sendto(hk, JSON.stringify([ "GET_FULL_HISTORY", data.channel, data.validateKey ]));
};
Store.getHistory = function(clientId, data, _cb, full) {
var cb = Util.once(Util.mkAsync(_cb));
var network = store.network;
var hk = network.historyKeeper;
var parse = function(msg) {
try {
return JSON.parse(msg);
} catch (e) {
return null;
}
};
var txid = Math.floor(Math.random() * 1e6);
var msgs = [];
var completed = false;
var onMsg = function(msg, sender) {
if (completed) {
return;
}
if (sender !== hk) {
return;
}
var parsed = parse(msg);
if (!parsed) {
return;
}
if (parsed.txid && parsed.txid !== txid) {
return;
}
if (parsed.validateKey && parsed.channel) {
return;
}
if (parsed.error && parsed.channel) {
if (parsed.channel === data.channel) {
network.off("message", onMsg);
completed = true;
cb({
error: parsed.error
});
}
return;
}
if (parsed.state === 1 && parsed.channel) {
if (parsed.channel !== data.channel) {
return;
}
cb(msgs);
network.off("message", onMsg);
completed = true;
return;
}
if (Array.isArray(parsed) && parsed[0] && parsed[0] !== txid) {
return;
}
if (parsed[3] !== data.channel) {
return;
}
if (parsed[4] && full) {
msgs.push({
msg,
hash: parsed[4].slice(0, 64)
});
return;
}
msg = parsed[4];
if (msg) {
msg = msg.replace(/cp\|(([A-Za-z0-9+\/=]+)\|)?/, "");
msgs.push(msg);
}
};
network.on("message", onMsg);
var cfg = {
txid,
lastKnownHash: data.lastKnownHash
};
var msg = [ "GET_HISTORY", data.channel, cfg ];
network.sendto(hk, JSON.stringify(msg));
};
Store.getHistoryRange = function(clientId, data, cb) {
var network = store.network;
var hk = network.historyKeeper;
var parse = function(msg) {
try {
return JSON.parse(msg);
} catch (e) {
return null;
}
};
var msgs = [];
var first = true;
var fullHistory = false;
var completed = false;
var lastKnownHash;
var txid = Util.uid();
var onMsg = function(msg) {
if (completed) {
return;
}
var parsed = parse(msg);
if (parsed[1] !== txid) {
console.log("bad txid");
return;
}
if (parsed[0] === "HISTORY_RANGE_ERROR") {
cb({
error: parsed[2]
});
return;
}
if (parsed[0] === "HISTORY_RANGE_END") {
cb({
messages: msgs,
isFull: fullHistory,
lastKnownHash
});
completed = true;
return;
}
if (parsed[0] !== "HISTORY_RANGE") {
return;
}
if (parsed[2] && parsed[1].validateKey) {
return;
}
if (parsed[2][3] !== data.channel) {
return;
}
msg = parsed[2][4];
if (msg) {
if (first) {
if (!/^cp\|/.test(msg) && !data.toHash) {
fullHistory = true;
}
lastKnownHash = msg.slice(0, 64);
first = false;
}
msg = msg.replace(/cp\|(([A-Za-z0-9+\/=]+)\|)?/, "");
msgs.push({
serverHash: msg.slice(0, 64),
msg,
author: parsed[2][1],
time: parsed[2][5]
});
}
};
network.on("message", onMsg);
network.sendto(hk, JSON.stringify([ "GET_HISTORY_RANGE", data.channel, {
from: data.lastKnownHash,
to: data.toHash,
cpCount: data.cpCount || 2,
txid
} ]));
};
var registerProxyEvents = function(proxy, fId) {
if (!proxy) {
return;
}
if (proxy.deprecated || proxy.restricted) {
return;
}
if (!fId) {
proxy.on("change", [ "drive", UserObject.SHARED_FOLDERS ], (function(o, n, p) {
if (p.length > 3 && p[3] === "password") {
var id = p[2];
var data = proxy.drive[UserObject.SHARED_FOLDERS][id];
var href = store.manager.user.userObject.getHref ? store.manager.user.userObject.getHref(data) : data.href;
var parsed = Hash.parsePadUrl(href);
var secret = Hash.getSecrets(parsed.type, parsed.hash, o);
SF.updatePassword(Store, {
oldChannel: secret.channel,
password: n,
href
}, store.network, (function() {
console.log("Shared folder password changed");
}));
return false;
}
}));
}
proxy.on("change", [], (function(o, n, p) {
if (fId) {
if (p[0] === UserObject.FILES_DATA && typeof n === "object" && n.channel && !n.owners) {
var toPin = [ n.channel ];
if (n.rtChannel) {
toPin.push(n.rtChannel);
}
if (n.lastVersion) {
toPin.push(n.lastVersion);
}
Store.pinPads(null, toPin, (function(obj) {
console.error(obj);
}));
}
if (p[0] === UserObject.FILES_DATA && typeof o === "object" && o.channel && !n) {
var toUnpin = [ o.channel ];
var c = store.manager.findChannel(o.channel);
var exists = c.some((function(data) {
return data.fId !== fId;
}));
if (!exists) {
if (o.rtChannel) {
toUnpin.push(o.rtChannel);
}
if (o.lastVersion) {
toUnpin.push(o.lastVersion);
}
Store.unpinPads(null, toUnpin, (function(obj) {
console.error(obj);
}));
}
}
}
if (o && !n && Array.isArray(p) && (p[0] === UserObject.FILES_DATA || p[0] === "drive" && p[1] === UserObject.FILES_DATA)) {
setTimeout((function() {
Store.checkDeletedPad(o && o.channel);
}));
}
sendDriveEvent("DRIVE_CHANGE", {
id: fId,
old: o,
new: n,
path: p
});
}));
proxy.on("remove", [], (function(o, p) {
sendDriveEvent("DRIVE_REMOVE", {
id: fId,
old: o,
path: p
});
}));
};
var addSharedFolderHandler = function() {
store.sharedFolders = {};
store.handleSharedFolder = function(id, rt) {
if (!rt) {
delete store.sharedFolders[id];
return;
}
store.sharedFolders[id] = rt;
if (store.driveEvents) {
registerProxyEvents(rt.proxy, id);
}
};
};
Store.loadSharedFolder = function(teamId, id, data, cb, isNew) {
var s = getStore(teamId);
if (!s) {
return void cb({
error: "ENOTFOUND"
});
}
var parsed = Hash.parsePadUrl(data.href || data.roHref);
if (!parsed && !parsed.hashData) {
return void cb({
error: "EINVAL"
});
}
SF.load({
isNew,
network: store.network || store.networkPromise,
store: s,
Store,
isNewChannel: Store.isNewChannel
}, id, data, cb);
};
var loadSharedFolder = function(id, data, cb, isNew) {
Store.loadSharedFolder(null, id, data, cb, isNew);
};
Store.loadSharedFolderAnon = function(clientId, data, cb) {
Store.loadSharedFolder(null, data.id, data.data, (function(rt) {
cb({
error: rt ? undefined : "EDELETED"
});
}));
};
Store.addSharedFolder = function(clientId, data, cb) {
onReadyEvt.reg((function() {
var s = getStore(data.teamId);
s.manager.addSharedFolder(data, (function(id) {
if (id && typeof id === "object" && id.error) {
return void cb(id);
}
var send = data.teamId ? s.sendEvent : sendDriveEvent;
send("DRIVE_CHANGE", {
path: [ "drive", UserObject.FILES_DATA ]
}, clientId);
cb(id);
}));
}));
};
Store.updateSharedFolderPassword = function(clientId, data, cb) {
SF.updatePassword(Store, data, store.network, cb);
};
Store.userObjectCommand = function(clientId, cmdData, cb) {
if (!cmdData || !cmdData.cmd) {
return;
}
var s = getStore(cmdData.teamId);
if (s.offline) {
var send = s.id ? s.sendEvent : sendDriveEvent;
send("NETWORK_DISCONNECT");
return void cb({
error: "OFFLINE"
});
}
var cb2 = function(data2) {
getAllStores().forEach((function(_s) {
var send = _s.id ? _s.sendEvent : sendDriveEvent;
send("DRIVE_CHANGE", {
path: [ "drive", UserObject.FILES_DATA ]
}, clientId);
}));
onSync(cmdData.teamId, (function() {
cb(data2);
}));
};
s.manager.command(cmdData, cb2);
};
var alwaysOnline = function(chanId) {
if (!store) {
return;
}
if (store.driveChannel === chanId) {
return true;
}
if (SF.isSharedFolderChannel(chanId)) {
return true;
}
if (Util.find(store, [ "proxy", "teams" ])) {
var t = Util.find(store, [ "proxy", "teams" ]) || {};
return Object.keys(t).some((function(id) {
return t[id].channel === chanId;
}));
}
if (Util.find(store, [ "proxy", "profile", "href" ])) {
return Hash.hrefToHexChannelId(Util.find(store, [ "proxy", "profile", "href" ])) === chanId;
}
};
var dropChannel = Store.dropChannel = function(chanId) {
console.error("Drop channel", chanId);
try {
store.messenger.leavePad(chanId);
} catch (e) {
console.error(e);
}
try {
store.modules["cursor"].leavePad(chanId);
} catch (e) {
console.error(e);
}
try {
store.modules["integration"].leavePad(chanId);
} catch (e) {
console.error(e);
}
try {
store.onlyoffice.leavePad(chanId);
} catch (e) {
console.error(e);
}
try {
if (alwaysOnline(chanId)) {
delete Store.channels[chanId];
return;
}
} catch (e) {
console.error(e);
}
try {
Cache.leaveChannel(chanId);
} catch (e) {
console.error(e);
}
if (!Store.channels[chanId]) {
return;
}
if (Store.channels[chanId].cpNf) {
Store.channels[chanId].cpNf.stop();
}
delete Store.channels[chanId];
};
Store._removeClient = function(clientId) {
var driveIdx = driveEventClients.indexOf(clientId);
if (driveIdx !== -1) {
driveEventClients.splice(driveIdx, 1);
}
try {
store.onlyoffice?.removeClient(clientId);
} catch (e) {
console.error(e);
}
try {
store.mailbox?.removeClient(clientId);
} catch (e) {
console.error(e);
}
Object.keys(store.modules).forEach((function(key) {
if (!store.modules[key]) {
return;
}
if (!store.modules[key].removeClient) {
return;
}
try {
store.modules[key].removeClient(clientId);
} catch (e) {
console.error(e);
}
}));
Object.keys(Store.channels).forEach((function(chanId) {
var chanIdx = Store.channels[chanId].clients.indexOf(clientId);
if (chanIdx !== -1) {
Store.channels[chanId].clients.splice(chanIdx, 1);
}
if (Store.channels[chanId].clients.length === 0) {
dropChannel(chanId);
}
}));
};
var loadOnlyOffice = function() {
if (store.onlyoffice) {
return;
}
store.onlyoffice = OnlyOffice.init(store, (function(ev, data, clients) {
clients.forEach((function(cId) {
postMessage(cId, "OO_EVENT", {
ev,
data
});
}));
}));
};
var loadMailbox = function(waitFor) {
store.mailbox = Mailbox.init({
Store,
store,
updateMetadata: function() {
broadcast([], "UPDATE_METADATA");
},
updateDrive: function() {
sendDriveEvent("DRIVE_CHANGE", {
path: [ "drive", "filesData" ]
});
},
pinPads: function(data, cb) {
Store.pinPads(null, data, cb);
}
}, waitFor, (function(ev, data, clients, _cb) {
var cb = Util.once(_cb || function() {});
clients.forEach((function(cId) {
postMessage(cId, "MAILBOX_EVENT", {
ev,
data
}, cb);
}));
}));
};
Store.refreshDriveUI = function() {
getAllStores().forEach((function(_s) {
var send = _s.id ? _s.sendEvent : sendDriveEvent;
send("DRIVE_CHANGE", {
path: [ "drive", UserObject.FILES_DATA ]
});
}));
};
var onCacheReady = function(clientId, _cb) {
const cb = Util.mkAsync(_cb);
var proxy = store.proxy;
var drive = store.drive;
if (store.manager) {
return void cb();
}
var unpin = function(data, cb) {
if (!store.loggedIn) {
return void cb();
}
Store.unpinPads(null, data, cb);
};
var pin = function(data, cb) {
if (!store.loggedIn) {
return void cb();
}
Store.pinPads(null, data, cb);
};
var manager = store.manager = ProxyManager.create(drive.proxy, {
onSync: function(cb) {
onSync(null, cb);
},
edPublic: proxy.edPublic,
pin,
unpin,
loadSharedFolder,
settings: proxy.settings,
removeOwnedChannel: function(channel, cb) {
Store.removeOwnedChannel("", channel, cb);
},
store,
Store
}, {
outer: true,
edPublic: store.proxy.edPublic,
loggedIn: store.loggedIn,
log: function(msg) {
sendDriveEvent("DRIVE_LOG", msg);
},
rt: drive.realtime
});
var userObject = store.userObject = manager.user.userObject;
nThen((function(waitFor) {
addSharedFolderHandler();
userObject.migrate(waitFor());
})).nThen((function(waitFor) {
console.error("START LOADING SF");
var network = store.network || store.networkPromise;
SF.loadSharedFolders(Store, network, store, drive.proxy, userObject, waitFor, (obj => {
var data = {
type: "sf",
progress: 100 * obj.progress / obj.max
};
postMessage(clientId, "LOADING_DRIVE", data);
}), true);
})).nThen((function(waitFor) {
console.error("SF CACHE READY");
loadUniversal(Team, "team", waitFor, clientId);
})).nThen((function(waitFor) {
console.error("TEAM CACHE READY");
loadUniversal(Calendar, "calendar", waitFor);
})).nThen((function() {
cb();
}));
};
const loadSyncModules = (waitFor = function() {}) => {
loadUniversal(Cursor, "cursor", waitFor);
loadUniversal(Integration, "integration", waitFor);
loadUniversal(Messenger, "messenger", waitFor);
loadUniversal(History, "history", waitFor);
loadOnlyOffice();
if (store) {
store.messenger = store.modules["messenger"];
}
};
var onReady = function(clientId, returned, cb) {
store.ready = true;
var proxy = store.proxy;
var manager = store.manager;
var userObject = store.userObject;
nThen((function(waitFor) {
if (!proxy.settings) {
proxy.settings = NEW_USER_SETTINGS;
}
if (!proxy.forms) {
proxy.forms = {};
}
if (!proxy.friends_pending) {
proxy.friends_pending = {};
}
if (!proxy.form_seed) {
proxy.form_seed = Hash.createChannelId();
}
if (!manager) {
onCacheReady(clientId, waitFor());
manager = store.manager;
userObject = store.userObject;
}
initAnonRpc(null, null, waitFor());
initRpc(null, null, waitFor());
postMessage(clientId, "LOADING_DRIVE", {
type: "migrate",
progress: 0
});
})).nThen((function(waitFor) {
if (typeof proxy.version === "undefined") {
proxy.version = 11;
}
Migrate(proxy, waitFor(), (function(version, progress) {
postMessage(clientId, "LOADING_DRIVE", {
type: "migrate",
progress
});
}), store);
})).nThen((function(waitFor) {
postMessage(clientId, "LOADING_DRIVE", {
type: "sf",
progress: 0
});
userObject.fixFiles();
SF.loadSharedFolders(Store, store.network, store, store.drive.proxy, userObject, waitFor, (obj => {
var data = {
type: "sf",
progress: 100 * obj.progress / obj.max
};
postMessage(clientId, "LOADING_DRIVE", data);
}));
loadSyncModules(waitFor);
loadUniversal(Profile, "profile", waitFor);
loadUniversal(Calendar, "calendar", waitFor);
if (store.modules["team"]) {
store.modules["team"].onReady(waitFor);
}
loadUniversal(Support, "support", waitFor);
})).nThen((function() {
console.error("SF & TEAM READY");
var requestLogin = function() {
broadcast([], "REQUEST_LOGIN");
};
if (store.loggedIn) {
arePinsSynced((function(err, yes) {
if (!yes) {
resetPins((function(err) {
if (err) {
return console.error(err);
}
console.log("RESET DONE");
}));
}
}));
if (typeof proxy.loginToken !== "number") {
proxy[Constants.tokenKey] = store.data.localToken || Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
}
returned[Constants.tokenKey] = proxy[Constants.tokenKey];
if (store.data.localToken && store.data.localToken !== proxy[Constants.tokenKey]) {
return void requestLogin();
}
}
returned.feedback = Util.find(proxy, [ "settings", "general", "allowUserFeedback" ]);
Feedback.init(returned.feedback);
store.returned = returned;
if (typeof cb === "function") {
cb(returned);
}
store.offline = false;
sendDriveEvent("NETWORK_RECONNECT");
broadcast([], "UPDATE_METADATA");
broadcast([], "STORE_READY", returned);
if (typeof proxy.uid !== "string" || proxy.uid.length !== 32) {
console.log("generating a persistent identifier");
proxy.uid = Hash.createChannelId();
}
if (store.loggedIn && (!Store.hasSigningKeys() || !Store.hasCurveKeys())) {
return void requestLogin();
}
proxy.on("change", [ Constants.displayNameKey ], (function(o, n) {
if (typeof n !== "string") {
return;
}
broadcast([], "UPDATE_METADATA");
}));
proxy.on("change", [ "profile" ], (function() {
broadcast([], "UPDATE_METADATA");
}));
proxy.on("change", [ "friends" ], (function(o, n, p) {
broadcast([], "UPDATE_METADATA");
if (!store.messenger) {
return;
}
if (o !== undefined) {
return;
}
var curvePublic = p.slice(-1)[0];
var friend = proxy.friends && proxy.friends[curvePublic];
store.messenger.onFriendAdded(friend);
}));
proxy.on("remove", [ "friends" ], (function(o, p) {
broadcast([], "UPDATE_METADATA");
if (!store.messenger) {
return;
}
var curvePublic = p[1];
if (!curvePublic) {
return;
}
if (p[2] !== "channel") {
return;
}
store.messenger.onFriendRemoved(curvePublic, o);
}));
proxy.on("change", [ "friends_pending" ], (function() {
broadcast([], "UPDATE_METADATA");
}));
proxy.on("remove", [ "friends_pending" ], (function() {
broadcast([], "UPDATE_METADATA");
}));
proxy.on("change", [ "settings" ], (function() {
broadcast([], "UPDATE_METADATA");
}));
proxy.on("change", [ Constants.tokenKey ], (function() {
if (store.isDeleted || proxy[Constants.tokenKey] === "DELETED") {
return;
}
broadcast([], "UPDATE_TOKEN", {
token: proxy[Constants.tokenKey]
});
}));
loadMailbox();
onReadyEvt.fire();
}));
};
const loadAccount = (clientId, data, cacheCb, cb) => {
if (store.accountModule) {
return store.accountModule;
}
const account = Account.init({
userHash: data.userHash,
anonHash: data.anonHash,
cache: data.cache,
form_seed: data.form_seed,
store,
broadcast,
postMessage
});
store.accountModule = account;
const {channel, onAccountReady, onAccountCacheReady, onDisconnect, onReconnect} = account;
store.driveChannel = channel;
onAccountCacheReady((returned => {
store.returned ||= returned;
cacheCb(returned);
}));
onAccountReady((returned => {
store.returned ||= returned;
cb(returned);
}));
onDisconnect((() => {
sendDriveEvent("NETWORK_DISCONNECT");
}));
onReconnect((() => {
sendDriveEvent("NETWORK_RECONNECT");
}));
const PING_INTERVAL = 12e4;
const MAX_PING = 3e4;
const MAX_FAILED_PING = 2;
setInterval((function() {
var clients = [];
Object.keys(Store.channels).forEach((function(chanId) {
var c = Store.channels[chanId].clients;
Array.prototype.push.apply(clients, c);
}));
clients = Util.deduplicateString(clients);
clients.forEach((function(cId) {
var nb = 0;
var ping = function() {
if (nb >= MAX_FAILED_PING) {
Store._removeClient(cId);
postMessage(cId, "TIMEOUT");
console.error("TIMEOUT", cId);
return;
}
nb++;
var to = setTimeout(ping, MAX_PING);
postMessage(cId, "PING", null, (function(err) {
if (err) {
console.error(err);
}
clearTimeout(to);
}));
};
ping();
}));
}), PING_INTERVAL);
return account;
};
const loadDrive = (clientId, data, cacheCb, cb) => {
const startDrive = Util.once((account => {
const drive = Drive.init({
account,
store,
broadcast,
postMessage
});
const {onDriveReady, onDriveCacheReady, onDisconnect, onReconnect} = drive;
onDriveCacheReady((() => {
cacheCb(store.returned);
}));
onDriveReady((() => {
cb(store.returned);
}));
onDisconnect((() => {}));
onReconnect((() => {}));
}));
const noop = () => {};
const account = loadAccount(clientId, data, noop, noop);
account.onAccountCacheReady((() => {
startDrive(account);
}));
account.onAccountReady((() => {
startDrive(account);
}));
};
Store.disableCache = function(clientId, disabled, cb) {
if (disabled) {
Cache.disable();
} else {
Cache.enable();
}
cb();
};
var initialized = false;
Store.hasDrive = function(clientId, data, cb) {
cb({
state: Boolean(store.proxy)
});
};
const loadHK = cb => {
if (store?.network?.historyKeeper) {
return setTimeout(cb);
}
const onNetwork = network => {
store.network ||= network;
const chan = "0000000000000000000000000000000000";
network.join(chan).then((function(wc) {
let hk;
wc.members.forEach((p => {
if (p.length === 16) {
hk = p;
}
}));
network.historyKeeper = hk;
wc.leave();
cb();
}), (function(err) {
console.error(err);
cb({
error: "GET_HK"
});
}));
};
if (store.network) {
return onNetwork(store.network);
}
store.networkPromise?.then(onNetwork);
};
var onNoDrive = function(clientId, cb, initRpc) {
var andThen = function() {
loadSyncModules();
let getAnon = () => {
initAnonRpc(null, null, (function() {
Feedback.send("NO_DRIVE", true);
cb({});
}));
};
if (initRpc) {
return initTempRpc(clientId, getAnon);
}
getAnon();
};
if (!store.network) {
var wsUrl = NetConfig.getWebsocketURL();
return void Netflux.connect(wsUrl).then((function(network) {
if (!store.network) {
store.network = network;
} else {
network.disconnect();
network = store.network;
}
loadHK((err => {
if (err) {
return void cb(err);
}
andThen();
}));
}), (function(err) {
console.error(err);
cb({
error: "OFFLINE"
});
}));
}
andThen();
};
const startCacheModules = (clientId, returned, cb) => {
onCacheReady(clientId, (function() {
cb(returned);
onCacheReadyEvt.fire();
}));
};
const startModules = (clientId, returned, cb) => {
if (store.manager) {
return void onCacheReadyEvt.reg((function() {
const onNetwork = _network => {
store.network ||= _network;
onReady(clientId, returned, (() => {
cb(returned);
}));
};
loadHK(onNetwork);
}));
}
onReady(clientId, returned, (() => {
cb(returned);
}));
};
const start = (clientId, data, cb) => {
const noDrive = data.neverDrive || data.noDrive && !data.userHash && !data.anonHash;
if (noDrive) {
if (data.neverDrive) {
store.neverCache = true;
}
return void onNoDrive(clientId, (obj => {
if (obj?.error) {
Feedback.send("NO_DRIVE_ERROR", true);
}
cb(obj);
}), !!data.neverDrive);
}
const requires = data.requires;
initialized = true;
store.data = data;
let onInit = ret => {
if (Object.keys(store.proxy).length === 1) {
Feedback.send("FIRST_APP_USE", true);
}
if (ret && ret.error) {
initialized = false;
}
};
if (requires === "pad") {
return void onNoDrive(clientId, (function(obj) {
if (obj && obj.error) {
return;
}
cb(obj);
let next = Util.once((() => {
loadDrive(clientId, data, (ret => {
startCacheModules(clientId, ret, onInit);
}), (ret => {
startModules(clientId, ret, onInit);
}));
}));
onJoinedEvt.reg(next);
onPadRejectedEvt.reg(next);
}));
}
if (requires === "file") {
return void onNoDrive(clientId, (function(obj) {
if (obj && obj.error) {
return;
}
cb(obj);
loadDrive(clientId, data, (ret => {
startCacheModules(clientId, ret, onInit);
}), (ret => {
startModules(clientId, ret, onInit);
}));
}));
}
if (requires === "team") {
const initTeams = Util.once((ret => {
nThen((w => {
loadUniversal(Team, "team", w, clientId);
})).nThen((() => {
cb(ret);
loadDrive(clientId, data, (ret => {
startCacheModules(clientId, ret, onInit);
}), (ret => {
startModules(clientId, ret, onInit);
}));
}));
}));
return void loadAccount(clientId, data, initTeams, initTeams);
}
if (requires === "drive") {
return void loadDrive(clientId, data, (ret => {
cb(ret);
startCacheModules(clientId, ret, onInit);
}), (ret => {
cb(ret);
startModules(clientId, ret, onInit);
}));
}
let done = ret => {
onInit(ret);
const redirect = Constants.prefersDriveRedirectKey;
const redirectPreference = Util.find(store, [ "proxy", "settings", "general", redirect ]);
ret[redirect] = redirectPreference;
cb(ret);
};
loadDrive(clientId, data, (ret => {
startCacheModules(clientId, ret, done);
}), (ret => {
startModules(clientId, ret, done);
}));
};
let subscribeToDrive = function(clientId) {
onCacheReadyEvt.reg((() => {
if (driveEventClients.indexOf(clientId) === -1) {
driveEventClients.push(clientId);
}
if (!store.driveEvents) {
store.driveEvents = true;
registerProxyEvents(store.proxy);
Object.keys(store.manager.folders).forEach((function(fId) {
var proxy = store.manager.folders[fId].proxy;
registerProxyEvents(proxy, fId);
}));
}
}));
};
Store.init = function(clientId, data, _callback) {
var callback = Util.once((function(obj) {
if (data.driveEvents) {
subscribeToDrive(clientId);
}
_callback(obj);
}));
if (initialized && !store.returned && data.cache) {
return void onCacheReadyEvt.reg((function() {
callback({
state: "ALREADY_INIT",
returned: store.cacheReturned
});
}));
}
if (initialized) {
if (store.networkTimeout) {
postMessage(clientId, "LOADING_DRIVE", {
type: "offline"
});
}
return void onReadyEvt.reg((function() {
callback({
state: "ALREADY_INIT",
returned: store.returned
});
}));
}
if (data.disableCache) {
Cache.disable();
}
if (data.noDrive && !data.requires) {
data.requires = "pad";
}
start(clientId, data, Util.once((obj => {
if (obj.error === "GET_HK") {
return void callback({
error: "ERROR"
});
}
callback(obj);
})));
};
onReadyEvt.reg((function() {
var inactiveTime = +new Date - CACHE_MAX_AGE * (24 * 3600 * 1e3);
Cache.getKeys((function(err, keys) {
if (err) {
return void console.error(err);
}
var next = function() {
if (!keys.length) {
return;
}
var key = keys.pop();
Cache.getTime(key, (function(err, atime) {
if (err) {
return void next();
}
if (!atime || atime < inactiveTime) {
Cache.clearChannel(key, next());
return;
}
next();
}));
};
next();
}));
}));
Store.disconnect = function() {
if (globalThis.accountDeletion) {
return;
}
if (!store.network) {
return;
}
store.network.disconnect();
};
return Store;
};
return {
setCustomize,
create
};
};
if (module.exports) {
module.exports = factory(undefined, requireJSON_sortify(), requireUserObject(), requireProxyManager(), requireMigrateUserObject(), requireCommonHash(), requireCommonUtil(), requireCommonConstants(), requireCommonFeedback(), requireCommonRealtime(), requireCommonMessaging(), requirePinpad(), requireRpc(), requireMergeDrive(), requireCacheStore(), requireSharedfolder(), require$$15, require$$16, requireCursor(), requireSupport(), requireIntegration(), requireOnlyoffice(), requireMailbox(), requireProfile(), requireTeam(), requireMessenger(), requireHistory(), requireCalendar(), requireLoginBlock(), requireNetworkConfig(), undefined, requireCrypto(), requireChainpad_dist(), requireChainpadNetflux(), requireChainpadListmap(), requireNetfluxClient(), requireNthen());
}
})();
})(asyncStore$1);
return asyncStore$1.exports;
}
var asyncStoreExports = requireAsyncStore();
var asyncStore = getDefaultExportFromCjs(asyncStoreExports);
var Store = _mergeNamespaces({
__proto__: null,
default: asyncStore
}, [ asyncStoreExports ]);
var _interface = {
exports: {}
};
var storeRpc = {
exports: {}
};
var hasRequiredStoreRpc;
function requireStoreRpc() {
if (hasRequiredStoreRpc) return storeRpc.exports;
hasRequiredStoreRpc = 1;
(function(module) {
(() => {
const factory = AStore => {
var create = function(config) {
var Store = AStore.create(config);
var Rpc = {};
var queries = Rpc.queries = {
CONNECT: Store.init,
DISCONNECT: Store.disconnect,
MIGRATE_ANON_DRIVE: Store.migrateAnonDrive,
PING: function(cId, data, cb) {
cb();
},
CACHE_DISABLE: Store.disableCache,
HAS_DRIVE: Store.hasDrive,
UPDATE_PIN_LIMIT: Store.updatePinLimit,
GET_PIN_LIMIT: Store.getPinLimit,
CLEAR_OWNED_CHANNEL: Store.clearOwnedChannel,
REMOVE_OWNED_CHANNEL: Store.removeOwnedChannel,
UPLOAD_CHUNK: Store.uploadChunk,
UPLOAD_COMPLETE: Store.uploadComplete,
UPLOAD_STATUS: Store.uploadStatus,
UPLOAD_CANCEL: Store.uploadCancel,
PIN_PADS: Store.pinPads,
UNPIN_PADS: Store.unpinPads,
GET_DELETED_PADS: Store.getDeletedPads,
GET_PINNED_USAGE: Store.getPinnedUsage,
ANON_RPC_MESSAGE: Store.anonRpcMsg,
GET_FILE_SIZE: Store.getFileSize,
GET_MULTIPLE_FILE_SIZE: Store.getMultipleFileSize,
GET: Store.get,
SET: Store.set,
GET_DRIVE: Store.drive.get,
SET_DRIVE: Store.drive.set,
ADD_PAD: Store.addPad,
SET_PAD_TITLE: Store.setPadTitle,
MOVE_TO_TRASH: Store.moveToTrash,
RESET_DRIVE: Store.resetDrive,
GET_METADATA: Store.getMetadata,
IS_ONLY_IN_SHARED_FOLDER: Store.isOnlyInSharedFolder,
SET_DISPLAY_NAME: Store.setDisplayName,
SET_PAD_ATTRIBUTE: Store.setPadAttribute,
GET_PAD_ATTRIBUTE: Store.getPadAttribute,
SET_ATTRIBUTE: Store.setAttribute,
GET_ATTRIBUTE: Store.getAttribute,
LIST_ALL_TAGS: Store.listAllTags,
GET_TEMPLATES: Store.getTemplates,
GET_SECURE_FILES_LIST: Store.getSecureFilesList,
GET_PAD_DATA: Store.getPadData,
GET_PAD_DATA_FROM_CHANNEL: Store.getPadDataFromChannel,
GET_STRONGER_HASH: Store.getStrongerHash,
INCREMENT_TEMPLATE_USE: Store.incrementTemplateUse,
GET_SHARED_FOLDER: Store.getSharedFolder,
ADD_SHARED_FOLDER: Store.addSharedFolder,
LOAD_SHARED_FOLDER: Store.loadSharedFolderAnon,
RESTORE_SHARED_FOLDER: Store.restoreSharedFolder,
UPDATE_SHARED_FOLDER_PASSWORD: Store.updateSharedFolderPassword,
ANSWER_FRIEND_REQUEST: Store.answerFriendRequest,
SEND_FRIEND_REQUEST: Store.sendFriendRequest,
ANON_GET_PREVIEW_CONTENT: Store.anonGetPreviewContent,
OO_COMMAND: Store.onlyoffice.execCommand,
MAILBOX_COMMAND: Store.mailbox.execCommand,
UNIVERSAL_COMMAND: Store.universal.execCommand,
SEND_PAD_MSG: Store.sendPadMsg,
JOIN_PAD: Store.joinPad,
LEAVE_PAD: Store.leavePad,
GET_FULL_HISTORY: Store.getFullHistory,
GET_HISTORY: Store.getHistory,
GET_HISTORY_RANGE: Store.getHistoryRange,
IS_NEW_CHANNEL: Store.isNewChannel,
CONTACT_PAD_OWNER: Store.contactPadOwner,
GIVE_PAD_ACCESS: Store.givePadAccess,
BURN_PAD: Store.burnPad,
GET_PAD_METADATA: Store.getPadMetadata,
SET_PAD_METADATA: Store.setPadMetadata,
CHANGE_PAD_PASSWORD_PIN: Store.changePadPasswordPin,
GET_LAST_HASH: Store.getLastHash,
GET_SNAPSHOT: Store.getSnapshot,
CORRUPTED_CACHE: Store.corruptedCache,
DELETE_MAILBOX_MESSAGE: Store.deleteMailboxMessage,
DRIVE_USEROBJECT: Store.userObjectCommand,
DELETE_ACCOUNT: Store.deleteAccount,
REMOVE_OWNED_PADS: Store.removeOwnedPads,
ADMIN_RPC: Store.adminRpc,
ADMIN_ADD_MAILBOX: Store.addAdminMailbox
};
Rpc.query = function(cmd, data, cb) {
if (queries[cmd]) {
queries[cmd]("0", data, cb);
} else {
console.error("UNHANDLED_STORE_RPC");
}
};
Rpc._removeClient = Store._removeClient;
return Rpc;
};
return {
create
};
};
if (module.exports) {
module.exports = factory(requireAsyncStore());
}
})();
})(storeRpc);
return storeRpc.exports;
}
var workerChannel = {
exports: {}
};
var hasRequiredWorkerChannel;
function requireWorkerChannel() {
if (hasRequiredWorkerChannel) return workerChannel.exports;
hasRequiredWorkerChannel = 1;
(function(module) {
(() => {
const factory = (Util, ApiConfig = {}) => {
var mkTxid = function() {
return Math.random().toString(16).replace("0.", "") + Math.random().toString(16).replace("0.", "");
};
var create = function(onMsg, postMsg, cb) {
var chanLoaded;
var waitingData = [];
var evReady = Util.mkEvent(true);
onMsg.reg((function(msg) {
if (chanLoaded) {
return;
}
var data = msg.data;
if (data === "_READY") {
postMsg("_READY");
chanLoaded = true;
evReady.fire();
waitingData.forEach((function(d) {
onMsg.fire(d);
}));
return;
}
waitingData.push(data);
}));
var handlers = {};
var queries = {};
var acks = {};
var insideHandlers = [];
var callWhenRegistered = {};
var chan = {};
chan.query = function(q, content, cb, opts) {
var txid = mkTxid();
opts = opts || {};
var to = opts.timeout || 3e4;
var timeout;
if (to > 0) {
timeout = setTimeout((function() {
delete queries[txid];
cb("TIMEOUT");
}), to);
}
acks[txid] = function(err) {
clearTimeout(timeout);
delete acks[txid];
if (err) {
delete queries[txid];
cb("UNHANDLED");
}
};
queries[txid] = function(data, msg) {
delete queries[txid];
cb(undefined, data.content, msg);
};
evReady.reg((function() {
var toSend = {
txid,
content,
q,
raw: opts.raw
};
postMsg(opts.raw ? toSend : JSON.stringify(toSend));
}));
};
var event = chan.event = function(e, content, opts) {
opts = opts || {};
evReady.reg((function() {
var toSend = {
content,
q: e,
raw: opts.raw
};
postMsg(opts.raw ? toSend : JSON.stringify(toSend));
}));
};
chan.on = function(queryType, handler, quiet) {
var h = function(data, msg, raw) {
handler(data.content, (function(replyContent) {
var toSend = {
txid: data.txid,
content: replyContent
};
postMsg(raw ? toSend : JSON.stringify(toSend));
}), msg);
};
(handlers[queryType] = handlers[queryType] || []).push(h);
if (!quiet) {
event("EV_REGISTER_HANDLER", queryType);
}
return {
stop: function() {
var idx = handlers[queryType].indexOf(h);
if (idx === -1) {
return;
}
handlers[queryType].splice(idx, 1);
}
};
};
chan.whenReg = function(queryType, cb, always) {
var reg = always;
if (insideHandlers.indexOf(queryType) > -1) {
cb();
} else {
reg = true;
}
if (reg) {
(callWhenRegistered[queryType] = callWhenRegistered[queryType] || []).push(cb);
}
};
chan.onReg = function(queryType, cb) {
chan.whenReg(queryType, cb, true);
};
chan.on("EV_REGISTER_HANDLER", (function(content) {
if (callWhenRegistered[content]) {
callWhenRegistered[content].forEach((function(f) {
f();
}));
delete callWhenRegistered[content];
}
insideHandlers.push(content);
}));
var isReady = false;
chan.onReady = function(h) {
if (isReady) {
return void h();
}
if (typeof h !== "function") {
return;
}
chan.on("EV_RPC_READY", (function() {
isReady = true;
h();
}));
};
chan.ready = function() {
chan.whenReg("EV_RPC_READY", (function() {
chan.event("EV_RPC_READY");
}));
};
var trusted = [ "" ];
if (ApiConfig.httpUnsafeOrigin) {
trusted.push(ApiConfig.httpUnsafeOrigin);
trusted.push(ApiConfig.httpSafeOrigin);
} else if (globalThis.location) {
trusted.push(globalThis.location.origin);
}
onMsg.reg((function(msg) {
if (!chanLoaded) {
return;
}
if (!msg.data || msg.data === "_READY") {
return;
}
if (!trusted.includes(msg.origin)) {
return;
}
var data;
try {
data = typeof msg.data === "object" ? msg.data : JSON.parse(msg.data);
} catch (err) {
console.warn(err);
return;
}
if (typeof data.ack !== "undefined") {
if (acks[data.txid]) {
acks[data.txid](!data.ack);
}
} else if (typeof data.q === "string") {
if (handlers[data.q]) {
if (data.txid) {
postMsg(JSON.stringify({
txid: data.txid,
ack: true
}));
}
handlers[data.q].forEach((function(f) {
f(data || JSON.parse(msg.data), msg, data && data.raw);
data = undefined;
}));
} else {
if (data.txid) {
postMsg(JSON.stringify({
txid: data.txid,
ack: false
}));
}
}
} else if (typeof data.q === "undefined" && queries[data.txid]) {
queries[data.txid](data, msg);
} else ;
}));
postMsg("_READY");
cb(chan);
};
return {
create
};
};
if (module.exports) {
module.exports = factory(requireCommonUtil());
}
})();
})(workerChannel);
return workerChannel.exports;
}
var hasRequired_interface;
function require_interface() {
if (hasRequired_interface) return _interface.exports;
hasRequired_interface = 1;
(function(module) {
(() => {
const factory = (SRpc, Channel, Util) => {
const Interface = {};
let store;
let Rpc;
let clients = {};
let closeStore = () => {};
Interface.init = _closeStore => {
if (Rpc) {
return;
}
const query = (cId, cmd, data, cb) => {
cb = cb || function() {};
clients[cId].chan.query(cmd, data, (function(err, res) {
if (err) {
return void cb({
error: err
});
}
cb(res);
}));
};
const broadcast = (excludes, cmd, data, cb) => {
cb = cb || function() {};
Object.keys(clients).forEach((cId => {
if (excludes.indexOf(+cId) !== -1) {
return;
}
clients[cId].chan.query(cmd, data, ((err, res) => {
if (err) {
return void cb({
error: err
});
}
cb(res);
}));
}));
};
Rpc = SRpc.create({
query,
broadcast
});
closeStore = _closeStore;
};
Interface.initClient = (cfg, cb) => {
if (!Rpc) {
console.error("Not initialized");
return void cb("NOT_INIT");
}
const {postMsg} = cfg;
const onMsg = Util.mkEvent();
const clientId = Number(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER));
const onClose = () => {
Rpc._removeClient(clientId);
};
Channel.create(onMsg, postMsg, (function(chan) {
let client = clients[clientId] = {
chan
};
console.debug("SharedW Channel created");
Object.keys(Rpc.queries).forEach((function(q) {
if (q === "CONNECT") {
return;
}
if (q === "JOIN_PAD") {
return;
}
if (q === "SEND_PAD_MSG") {
return;
}
if (q === "STOPWORKER") {
return;
}
chan.on(q, (function(data, cb) {
try {
Rpc.queries[q](clientId, data, cb);
} catch (e) {
console.error("Error in webworker when executing query " + q);
console.error(e);
console.log(data);
}
if (q === "DISCONNECT") {
onClose();
if (globalThis.accountDeletion && globalThis.accountDeletion === client.id) {
Rpc = undefined;
store = undefined;
}
}
}));
}));
chan.on("STOPWORKER", (function(data, cb) {
closeStore();
Rpc.queries["DISCONNECT"](clientId, data, cb);
}));
chan.on("CONNECT", (function(cfg, cb) {
console.debug("Connecting to store...");
Rpc.queries["CONNECT"](clientId, cfg, (function(data) {
if (data && data.state === "ALREADY_INIT") {
console.debug("Store already exists!");
store = store || data.returned;
return void cb(data);
}
store = data;
cb(data);
}));
}));
chan.on("JOIN_PAD", (function(data, cb) {
client.channelId = data.channel;
try {
Rpc.queries["JOIN_PAD"](clientId, data, cb);
} catch (e) {
console.error("Error in webworker when executing query JOIN_PAD");
console.error(e);
console.log(data);
}
}));
chan.on("SEND_PAD_MSG", (function(msg, cb) {
var data = {
msg,
channel: client.channelId
};
try {
Rpc.queries["SEND_PAD_MSG"](clientId, data, cb);
} catch (e) {
console.error("Error in webworker when executing query SEND_PAD_MSG");
console.error(e);
console.log(data);
}
}));
cb(onMsg, onClose);
}), true);
};
return Interface;
};
if (module.exports) {
module.exports = factory(requireStoreRpc(), requireWorkerChannel(), requireCommonUtil());
}
})();
})(_interface);
return _interface.exports;
}
var swConnector;
var hasRequiredSwConnector;
function requireSwConnector() {
if (hasRequiredSwConnector) return swConnector;
hasRequiredSwConnector = 1;
const Interface = require_interface();
let start = setConfig => {
let ready = false;
let closeStore = () => {
globalThis.close();
};
let initBuild = cfg => {
if (ready) {
return;
}
setConfig(cfg);
Interface.init(closeStore);
ready = true;
};
globalThis.window = globalThis;
addEventListener("connect", (e => {
console.error("TEST");
console.debug("New SharedWorker client");
const port = e.ports[0];
const postMsg = data => {
port.postMessage(data);
};
console.error(port);
let connected = false;
let onMsg;
let onClose = () => {};
port.onmessage = function(e) {
if (e.data?.type === "INIT") {
let cfg = e.data.cfg;
initBuild(cfg);
if (connected) {
return;
}
connected = true;
Interface.initClient({
postMsg
}, (function(_onMsg, _onClose) {
onMsg = _onMsg;
onClose = _onClose;
postMsg("SW_READY");
}));
} else if (e.data === "CLOSE") {
console.debug("leave");
onClose();
} else if (onMsg) {
onMsg.fire(e);
}
};
}));
};
swConnector = {
start
};
return swConnector;
}
var swConnectorExports = requireSwConnector();
var wwConnector;
var hasRequiredWwConnector;
function requireWwConnector() {
if (hasRequiredWwConnector) return wwConnector;
hasRequiredWwConnector = 1;
const Interface = require_interface();
let start = setConfig => {
let onMsg;
let ready = false;
const closeStore = () => {
globalThis.close();
};
const postMsg = data => {
postMessage(data);
};
globalThis.window = globalThis;
onmessage = function(e) {
if (e.data?.type === "INIT") {
let cfg = e.data.cfg;
if (ready) {
return;
}
setConfig(cfg);
Interface.init(closeStore);
ready = true;
Interface.initClient({
postMsg
}, (function(_onMsg) {
onMsg = _onMsg;
postMsg("WW_READY");
}));
return;
}
if (!onMsg) {
return;
}
onMsg.fire(e);
};
};
wwConnector = {
start
};
return wwConnector;
}
var wwConnectorExports = requireWwConnector();
var asyncConnector;
var hasRequiredAsyncConnector;
function requireAsyncConnector() {
if (hasRequiredAsyncConnector) return asyncConnector;
hasRequiredAsyncConnector = 1;
const Interface = require_interface();
const Util = requireCommonUtil();
let start = setConfig => {
let ready = false;
let closed = false;
let onMsg;
const sendMsgEv = Util.mkEvent();
const closeStore = () => {
closed = true;
};
const onMessage = f => {
sendMsgEv.reg((data => {
setTimeout((() => {
f(data);
}));
}));
};
const postMsg = data => {
if (closed) {
return;
}
sendMsgEv.fire(data);
};
const query = data => {
if (!onMsg || closed) {
return;
}
onMsg.fire({
data,
origin: ""
});
};
let init = cfg => {
if (ready) {
return;
}
setConfig(cfg);
Interface.init(closeStore);
ready = true;
Interface.initClient({
postMsg
}, (function(_onMsg) {
onMsg = _onMsg;
postMsg("STORE_READY");
}));
};
return {
init,
onMessage,
query
};
};
asyncConnector = {
start
};
return asyncConnector;
}
var asyncConnectorExports = requireAsyncConnector();
var migrateUserObjectExports = requireMigrateUserObject();
var migrateUserObject = getDefaultExportFromCjs(migrateUserObjectExports);
var Migrate = _mergeNamespaces({
__proto__: null,
default: migrateUserObject
}, [ migrateUserObjectExports ]);
var mailboxExports = requireMailbox();
var mailbox = getDefaultExportFromCjs(mailboxExports);
var Mailbox = _mergeNamespaces({
__proto__: null,
default: mailbox
}, [ mailboxExports ]);
var cursorExports = requireCursor();
var cursor = getDefaultExportFromCjs(cursorExports);
var Cursor = _mergeNamespaces({
__proto__: null,
default: cursor
}, [ cursorExports ]);
var supportExports = requireSupport();
var support = getDefaultExportFromCjs(supportExports);
var Support = _mergeNamespaces({
__proto__: null,
default: support
}, [ supportExports ]);
var calendarExports = requireCalendar();
var calendar = getDefaultExportFromCjs(calendarExports);
var Calendar = _mergeNamespaces({
__proto__: null,
default: calendar
}, [ calendarExports ]);
let start = cfg => {
[ Feedback, UO, Constants, ProxyManager, NetworkConfig, Migrate, LoginBlock, PadTypes, Credential, Cursor, Support, Calendar, Store, Account, Mailbox ].forEach((dep => {
if (typeof dep.setCustomize === "function") {
dep.setCustomize(cfg);
}
}));
};
let inWorker = typeof WorkerGlobalScope !== "undefined" && self instanceof WorkerGlobalScope;
let inSharedWorker = typeof SharedWorkerGlobalScope !== "undefined" && self instanceof SharedWorkerGlobalScope;
exports.store = {};
if (inSharedWorker) {
console.error("SHAREDWORKER");
swConnectorExports.start(start);
} else if (inWorker) {
console.error("WEBWORKER");
wwConnectorExports.start(start);
} else if (typeof module !== "undefined" && typeof module.exports) {
console.error("NODEJS");
exports.store = asyncConnectorExports.start(start);
} else {
console.error("BROWSER");
exports.store = asyncConnectorExports.start(start);
}
exports.start = start;
}));