PK :~Tϫ..index.js(function (global, factory) { if (typeof define === "function" && define.amd) { define(["exports"], factory); } else if (typeof exports !== "undefined") { factory(exports); } else { var mod = { exports: {} }; factory(mod.exports); global.unknown = mod.exports; } })(this, function (_exports) { "use strict"; Object.defineProperty(_exports, "__esModule", { value: true }); _exports.default = void 0; !function (global) { "use strict"; var Op = Object.prototype; var hasOwn = Op.hasOwnProperty; var undefined; var $Symbol = typeof Symbol === "function" ? Symbol : {}; var iteratorSymbol = $Symbol.iterator || "@@iterator"; var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; var inModule = typeof module === "object"; var runtime = global.regeneratorRuntime; if (runtime) { if (inModule) { module.exports = runtime; } return; } runtime = global.regeneratorRuntime = inModule ? module.exports || {} : {}; function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; var generator = Object.create(protoGenerator.prototype); var context = new Context(tryLocsList || []); generator._invoke = makeInvokeMethod(innerFn, self, context); return generator; } runtime.wrap = wrap; function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } var GenStateSuspendedStart = "suspendedStart"; var GenStateSuspendedYield = "suspendedYield"; var GenStateExecuting = "executing"; var GenStateCompleted = "completed"; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; IteratorPrototype[iteratorSymbol] = function () { return this; }; var getProto = Object.getPrototypeOf; var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { IteratorPrototype = NativeIteratorPrototype; } var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; GeneratorFunctionPrototype.constructor = GeneratorFunction; GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = "GeneratorFunction"; function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { prototype[method] = function (arg) { return this._invoke(method, arg); }; }); } runtime.isGeneratorFunction = function (genFun) { var ctor = typeof genFun === "function" && genFun.constructor; return ctor ? ctor === GeneratorFunction || (ctor.displayName || ctor.name) === "GeneratorFunction" : false; }; runtime.mark = function (genFun) { if (Object.setPrototypeOf) { Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); } else { genFun.__proto__ = GeneratorFunctionPrototype; if (!(toStringTagSymbol in genFun)) { genFun[toStringTagSymbol] = "GeneratorFunction"; } } genFun.prototype = Object.create(Gp); return genFun; }; runtime.awrap = function (arg) { return { __await: arg }; }; function AsyncIterator(generator) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if (record.type === "throw") { reject(record.arg); } else { var result = record.arg; var value = result.value; if (value && typeof value === "object" && hasOwn.call(value, "__await")) { return Promise.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }); } return Promise.resolve(value).then(function (unwrapped) { result.value = unwrapped; resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } } var previousPromise; function enqueue(method, arg) { function callInvokeWithMethodAndArg() { return new Promise(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } this._invoke = enqueue; } defineIteratorMethods(AsyncIterator.prototype); AsyncIterator.prototype[asyncIteratorSymbol] = function () { return this; }; runtime.AsyncIterator = AsyncIterator; runtime.async = function (innerFn, outerFn, self, tryLocsList) { var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList)); return runtime.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }; function makeInvokeMethod(innerFn, self, context) { var state = GenStateSuspendedStart; return function invoke(method, arg) { if (state === GenStateExecuting) { throw new Error("Generator is already running"); } if (state === GenStateCompleted) { if (method === "throw") { throw arg; } return doneResult(); } context.method = method; context.arg = arg; while (true) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if (context.method === "next") { context.sent = context._sent = context.arg; } else if (context.method === "throw") { if (state === GenStateSuspendedStart) { state = GenStateCompleted; throw context.arg; } context.dispatchException(context.arg); } else if (context.method === "return") { context.abrupt("return", context.arg); } state = GenStateExecuting; var record = tryCatch(innerFn, self, context); if (record.type === "normal") { state = context.done ? GenStateCompleted : GenStateSuspendedYield; if (record.arg === ContinueSentinel) { continue; } return { value: record.arg, done: context.done }; } else if (record.type === "throw") { state = GenStateCompleted; context.method = "throw"; context.arg = record.arg; } } }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (method === undefined) { context.delegate = null; if (context.method === "throw") { if (delegate.iterator.return) { context.method = "return"; context.arg = undefined; maybeInvokeDelegate(delegate, context); if (context.method === "throw") { return ContinueSentinel; } } context.method = "throw"; context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if (record.type === "throw") { context.method = "throw"; context.arg = record.arg; context.delegate = null; return ContinueSentinel; } var info = record.arg; if (!info) { context.method = "throw"; context.arg = new TypeError("iterator result is not an object"); context.delegate = null; return ContinueSentinel; } if (info.done) { context[delegate.resultName] = info.value; context.next = delegate.nextLoc; if (context.method !== "return") { context.method = "next"; context.arg = undefined; } } else { return info; } context.delegate = null; return ContinueSentinel; } defineIteratorMethods(Gp); Gp[toStringTagSymbol] = "Generator"; Gp[iteratorSymbol] = function () { return this; }; Gp.toString = function () { return "[object Generator]"; }; function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; if (1 in locs) { entry.catchLoc = locs[1]; } if (2 in locs) { entry.finallyLoc = locs[2]; entry.afterLoc = locs[3]; } this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal"; delete record.arg; entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }]; tryLocsList.forEach(pushTryEntry, this); this.reset(true); } runtime.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } keys.reverse(); return function next() { while (keys.length) { var key = keys.pop(); if (key in object) { next.value = key; next.done = false; return next; } } next.done = true; return next; }; }; function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) { return iteratorMethod.call(iterable); } if (typeof iterable.next === "function") { return iterable; } if (!isNaN(iterable.length)) { var i = -1, next = function next() { while (++i < iterable.length) { if (hasOwn.call(iterable, i)) { next.value = iterable[i]; next.done = false; return next; } } next.value = undefined; next.done = true; return next; }; return next.next = next; } } return { next: doneResult }; } runtime.values = values; function doneResult() { return { value: undefined, done: true }; } Context.prototype = { constructor: Context, reset: function (skipTempReset) { this.prev = 0; this.next = 0; this.sent = this._sent = undefined; this.done = false; this.delegate = null; this.method = "next"; this.arg = undefined; this.tryEntries.forEach(resetTryEntry); if (!skipTempReset) { for (var name in this) { if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) { this[name] = undefined; } } } }, stop: function () { this.done = true; var rootEntry = this.tryEntries[0]; var rootRecord = rootEntry.completion; if (rootRecord.type === "throw") { throw rootRecord.arg; } return this.rval; }, dispatchException: function (exception) { if (this.done) { throw exception; } var context = this; function handle(loc, caught) { record.type = "throw"; record.arg = exception; context.next = loc; if (caught) { context.method = "next"; context.arg = undefined; } return !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; var record = entry.completion; if (entry.tryLoc === "root") { return handle("end"); } if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"); var hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true); } else if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc); } } else if (hasCatch) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true); } } else if (hasFinally) { if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc); } } else { throw new Error("try statement without catch or finally"); } } } }, abrupt: function (type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) { finallyEntry = null; } var record = finallyEntry ? finallyEntry.completion : {}; record.type = type; record.arg = arg; if (finallyEntry) { this.method = "next"; this.next = finallyEntry.finallyLoc; return ContinueSentinel; } return this.complete(record); }, complete: function (record, afterLoc) { if (record.type === "throw") { throw record.arg; } if (record.type === "break" || record.type === "continue") { this.next = record.arg; } else if (record.type === "return") { this.rval = this.arg = record.arg; this.method = "return"; this.next = "end"; } else if (record.type === "normal" && afterLoc) { this.next = afterLoc; } return ContinueSentinel; }, finish: function (finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) { this.complete(entry.completion, entry.afterLoc); resetTryEntry(entry); return ContinueSentinel; } } }, "catch": function (tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if (record.type === "throw") { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function (iterable, resultName, nextLoc) { this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }; if (this.method === "next") { this.arg = undefined; } return ContinueSentinel; } }; }(function () { return this || typeof self === "object" && self; }() || Function("return this")()); const disableBlocks = { debug: [], upload: [] }; const mustLoginBlocks = []; const triggerBlocksStatus = async (mode, app) => {}; class ExtImpl {} const extTranslationMap = { "zh": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "de": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "es": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "fr": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "id": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "ja": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "ja-jph": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "ko": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "pl": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "uk": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "zh-hant": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "nl": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "it": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "hr": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "ru": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "pt": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "fi": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "tr": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "tk": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" }, "en": { "vdr_grove_lora": "vdr grove Lora", "extensionName": "vdr grove Lora", "extensionDescription": "", "BLOCK_1653809874148_FREQUENCE_0": "433Mhz", "BLOCK_1653809874148_FREQUENCE_1": "868Mhz", "BLOCK_1653809874148_PINDIGIT_0": "D2", "BLOCK_1653809874148_PINDIGIT_1": "D3", "BLOCK_1653809874148_PINDIGIT_2": "D4", "BLOCK_1653809874148_PINDIGIT_3": "D5", "BLOCK_1653809874148_PINDIGIT_4": "D6", "BLOCK_1653809874148_PINDIGIT_5": "D7", "BLOCK_1653809874148_PINDIGIT_6": "D8", "BLOCK_1653809874148_NBDATA_0": "5", "BLOCK_1653809874148_NBDATA_1": "10", "BLOCK_1653809874148_NBDATA_2": "15", "BLOCK_1653809874148_NBDATA_3": "20", "BLOCK_1653809874148_NBDATA_4": "texte", "BLOCK_1653809874148": "Initialiser Lora [frequence] [pinDigit] nombre de données [nbData] ", "BLOCK_1653809874506": "Définir donnée n°[index] à [data] ", "BLOCK_1653809874838": "Lire donnée n° [index]", "BLOCK_1653809875114": "Effacer données", "BLOCK_1653809875483": "Envoyer données", "BLOCK_1653809875786": "Reception de données", "BLOCK_1653809876062": "Lire text", "BLOCK_1653809876310": "Envoyer text [data] ", "BLOCK_1653809876594": "Texte reçu", "cate_25f02c8a": "vdr grove Lora" } }; const codeSnippets = { arduinoc: {} }; const extGenerators = [{ lang: 'arduinoc', template: `// generated by mBlock5 for // codes make you happy //( include //) #include //( lib //) //({ this.$ALL_VARIABLES.length==0?'':this.$ALL_VARIABLES.map(v=>"float "+v+" = 0;").join('\\n') }//) //( declare //) void _delay(float seconds) { long endTime = millis() + seconds * 1000; while(millis() < endTime) _loop(); } //( void setup() { //( setup //) //( code //) } //) void _loop() { //( _loop //) } void loop() { _loop(); }`, splitor: { frame: { left: "//(", right: "//)" }, expression: { left: "/*{", right: "}*/" } }, reducers: [{ name: 'include', reduce: codes => { let codes1 = []; for (let code of codes) { let codeStr = ''; if (typeof code === 'string') { codeStr = code; } else if (typeof code === 'function') { codeStr = code(); } if (codes1.indexOf(codeStr) === -1) { codes1.push(codeStr); } } if (codes1.length === 0) { return undefined; } return codes1.map(code => { return '#include ' + code; }).join('\n') + '\n'; } }] }]; const extSources = { arduino: [{ filename: "src/atomic.h", code: "/*\n This is port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3\n v1.0\n Mark Pendrith, Nov 27, 2012.\n\n From Mark:\n >When I ported the macros I emailed Dean to ask what attribution would be\n >appropriate, and here is his response:\n >\n >>Mark,\n >>I think it's great that you've ported the macros; consider them\n >>public domain, to do with whatever you wish. I hope you find them >useful .\n >>\n >>Cheers!\n >>- Dean\n*/\n\n#ifdef __arm__\n#ifndef _CORTEX_M3_ATOMIC_H_\n#define _CORTEX_M3_ATOMIC_H_\n\nstatic __inline__ uint32_t __get_primask(void) \\\n{\n uint32_t primask = 0; \\\n __asm__ volatile(\"MRS %[result], PRIMASK\\n\\t\":[result]\"=r\"(primask)::); \\\n return primask;\n} // returns 0 if interrupts enabled, 1 if disabled\n\nstatic __inline__ void __set_primask(uint32_t setval) \\\n{\n __asm__ volatile(\"MSR PRIMASK, %[value]\\n\\t\"\"dmb\\n\\t\"\"dsb\\n\\t\"\"isb\\n\\t\"::[value]\"r\"(setval):);\n __asm__ volatile(\"\" ::: \"memory\");\n}\n\nstatic __inline__ uint32_t __iSeiRetVal(void) \\\n{\n __asm__ volatile(\"CPSIE i\\n\\t\"\"dmb\\n\\t\"\"dsb\\n\\t\"\"isb\\n\\t\"); \\\n __asm__ volatile(\"\" ::: \"memory\"); return 1;\n}\n\nstatic __inline__ uint32_t __iCliRetVal(void) \\\n{\n __asm__ volatile(\"CPSID i\\n\\t\"\"dmb\\n\\t\"\"dsb\\n\\t\"\"isb\\n\\t\"); \\\n __asm__ volatile(\"\" ::: \"memory\"); return 1;\n}\n\nstatic __inline__ void __iSeiParam(const uint32_t* __s) \\\n{\n __asm__ volatile(\"CPSIE i\\n\\t\"\"dmb\\n\\t\"\"dsb\\n\\t\"\"isb\\n\\t\"); \\\n __asm__ volatile(\"\" ::: \"memory\"); (void)__s;\n}\n\nstatic __inline__ void __iCliParam(const uint32_t* __s) \\\n{\n __asm__ volatile(\"CPSID i\\n\\t\"\"dmb\\n\\t\"\"dsb\\n\\t\"\"isb\\n\\t\"); \\\n __asm__ volatile(\"\" ::: \"memory\"); (void)__s;\n}\n\nstatic __inline__ void __iRestore(const uint32_t* __s) \\\n{\n __set_primask(*__s); __asm__ volatile(\"dmb\\n\\t\"\"dsb\\n\\t\"\"isb\\n\\t\"); \\\n __asm__ volatile(\"\" ::: \"memory\");\n}\n\n\n#define ATOMIC_BLOCK(type) \\\n for ( type, __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0 )\n\n#define ATOMIC_RESTORESTATE \\\n uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask()\n\n#define ATOMIC_FORCEON \\\n uint32_t primask_save __attribute__((__cleanup__(__iSeiParam))) = 0\n\n#define NONATOMIC_BLOCK(type) \\\n for ( type, __ToDo = __iSeiRetVal(); __ToDo ; __ToDo = 0 )\n\n#define NONATOMIC_RESTORESTATE \\\n uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask()\n\n#define NONATOMIC_FORCEOFF \\\n uint32_t primask_save __attribute__((__cleanup__(__iCliParam))) = 0\n\n#endif\n#endif\n" }, { filename: "src/RadioHead.h", code: "#ifndef RadioHead_h\n#define RadioHead_h\n\n// Official version numbers are maintained automatically by Makefile:\n#define RH_VERSION_MAJOR 1\n#define RH_VERSION_MINOR 57\n\n// Symbolic names for currently supported platform types\n#define RH_PLATFORM_ARDUINO 1\n#define RH_PLATFORM_MSP430 2\n#define RH_PLATFORM_STM32 3\n#define RH_PLATFORM_GENERIC_AVR8 4\n#define RH_PLATFORM_UNO32 5\n#define RH_PLATFORM_UNIX 6\n#define RH_PLATFORM_STM32STD 7\n#define RH_PLATFORM_STM32F4_HAL 8\n#define RH_PLATFORM_RASPI 9\n#define RH_PLATFORM_NRF51 10\n#define RH_PLATFORM_ESP8266 11\n#define RH_PLATFORM_STM32F2 12\n\n////////////////////////////////////////////////////\n// Select platform automatically, if possible\n#ifndef RH_PLATFORM\n #if defined(MPIDE)\n #define RH_PLATFORM RH_PLATFORM_UNO32\n #elif defined(NRF51)\n #define RH_PLATFORM RH_PLATFORM_NRF51\n #elif defined(ESP8266)\n #define RH_PLATFORM RH_PLATFORM_ESP8266\n #elif defined(ARDUINO)\n #define RH_PLATFORM RH_PLATFORM_ARDUINO\n #elif defined(__MSP430G2452__) || defined(__MSP430G2553__)\n #define RH_PLATFORM RH_PLATFORM_MSP430\n #elif defined(MCU_STM32F103RE)\n #define RH_PLATFORM RH_PLATFORM_STM32\n #elif defined(STM32F2XX)\n #define RH_PLATFORM RH_PLATFORM_STM32F2\n #elif defined(USE_STDPERIPH_DRIVER)\n #define RH_PLATFORM RH_PLATFORM_STM32STD\n #elif defined(RASPBERRY_PI)\n #define RH_PLATFORM RH_PLATFORM_RASPI\n #elif defined(__unix__) // Linux\n #define RH_PLATFORM RH_PLATFORM_UNIX\n #elif defined(__APPLE__) // OSX\n #define RH_PLATFORM RH_PLATFORM_UNIX\n #else\n #error Platform not defined!\n #endif\n#endif\n\n#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtinyX4__) || defined(__AVR_ATtinyX5__) || defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny4313__) || defined(__AVR_ATtinyX313__)\n #define RH_PLATFORM_ATTINY\n#endif\n\n////////////////////////////////////////////////////\n// Platform specific headers:\n#if (RH_PLATFORM == RH_PLATFORM_ARDUINO)\n #if (ARDUINO >= 100)\n #include \n #endif\n#endif\n\n////////////////////////////////////////////////////\n// This is an attempt to make a portable atomic block\n#if (RH_PLATFORM == RH_PLATFORM_ARDUINO)\n #if defined(__arm__)\n #include \n #endif\n #define ATOMIC_BLOCK_START ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {\n #define ATOMIC_BLOCK_END }\n#endif\n\n////////////////////////////////////////////////////\n// Try to be compatible with systems that support yield() and multitasking\n// instead of spin-loops\n// Recent Arduino IDE or Teensy 3 has yield()\n#if (RH_PLATFORM == RH_PLATFORM_ARDUINO && ARDUINO >= 155 && !defined(RH_PLATFORM_ATTINY)) || (TEENSYDUINO && defined(__MK20DX128__))\n #define YIELD yield();\n#endif\n\n////////////////////////////////////////////////////\n// digitalPinToInterrupt is not available prior to Arduino 1.5.6 and 1.0.6\n// See http://arduino.cc/en/Reference/attachInterrupt\n#ifndef NOT_AN_INTERRUPT\n #define NOT_AN_INTERRUPT -1\n#endif\n#ifndef digitalPinToInterrupt\n\n // All other arduino except Due:\n // Serial Arduino, Extreme, NG, BT, Uno, Diecimila, Duemilanove, Nano, Menta, Pro, Mini 04, Fio, LilyPad, Ethernet etc\n // 2->0, 3->1\n #define digitalPinToInterrupt(p) ((p) == 2 ? 0 : ((p) == 3 ? 1 : NOT_AN_INTERRUPT))\n\n#endif\n\n// On some platforms, attachInterrupt() takes a pin number, not an interrupt number\n#if (RH_PLATFORM == RH_PLATFORM_ARDUINO) && defined (__arm__) && (defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_SAM_DUE))\n #define RH_ATTACHINTERRUPT_TAKES_PIN_NUMBER\n#endif\n\n// Slave select pin, some platforms such as ATTiny do not define it.\n#ifndef SS\n #define SS 10\n#endif\n\n// These defs cause trouble on some versions of Arduino\n#undef abs\n#undef round\n#undef double\n\n// Sigh: there is no widespread adoption of htons and friends in the base code, only in some WiFi headers etc\n// that have a lot of excess baggage\n#if RH_PLATFORM != RH_PLATFORM_UNIX && !defined(htons)\n// #ifndef htons\n// These predefined macros availble on modern GCC compilers\n#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n// Atmel processors\n#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) )\n#define ntohs(x) htons(x)\n#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \\\n ((x)<< 8 & 0x00FF0000UL) | \\\n ((x)>> 8 & 0x0000FF00UL) | \\\n ((x)>>24 & 0x000000FFUL) )\n#define ntohl(x) htonl(x)\n\n#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__\n// Others\n#define htons(x) (x)\n#define ntohs(x) (x)\n#define htonl(x) (x)\n#define ntohl(x) (x)\n\n#else\n#error \"Dont know how to define htons and friends for this processor\"\n#endif\n#endif\n\n// This is the address that indicates a broadcast\n#define RH_BROADCAST_ADDRESS 0xff\n\n#endif\n" }, { filename: "src/RHGenericDriver.cpp", code: "// RHGenericDriver.cpp\n//\n// Copyright (C) 2014 Mike McCauley\n// $Id: RHGenericDriver.cpp,v 1.19 2015/12/11 01:10:24 mikem Exp $\n\n#include \"RHGenericDriver.h\"\n\nRHGenericDriver::RHGenericDriver()\n :\n _mode(RHModeInitialising),\n _thisAddress(RH_BROADCAST_ADDRESS),\n _txHeaderTo(RH_BROADCAST_ADDRESS),\n _txHeaderFrom(RH_BROADCAST_ADDRESS),\n _txHeaderId(0),\n _txHeaderFlags(0),\n _rxBad(0),\n _rxGood(0),\n _txGood(0) {\n}\n\nbool RHGenericDriver::init() {\n return true;\n}\n\n// Blocks until a valid message is received\nvoid RHGenericDriver::waitAvailable() {\n while (!available()) {\n YIELD;\n }\n}\n\n// Blocks until a valid message is received or timeout expires\n// Return true if there is a message available\n// Works correctly even on millis() rollover\nbool RHGenericDriver::waitAvailableTimeout(uint16_t timeout) {\n unsigned long starttime = millis();\n while ((millis() - starttime) < timeout) {\n if (available()) {\n return true;\n }\n YIELD;\n }\n return false;\n}\n\nbool RHGenericDriver::waitPacketSent() {\n while (_mode == RHModeTx) {\n available();\n YIELD; // Wait for any previous transmit to finish\n }\n\n return true;\n}\n\nbool RHGenericDriver::waitPacketSent(uint16_t timeout) {\n unsigned long starttime = millis();\n while ((millis() - starttime) < timeout) {\n if (_mode != RHModeTx) { // Any previous transmit finished?\n return true;\n }\n available();\n YIELD;\n }\n return false;\n}\n\nvoid RHGenericDriver::setPromiscuous(bool promiscuous) {\n _promiscuous = promiscuous;\n}\n\nvoid RHGenericDriver::setThisAddress(uint8_t address) {\n _thisAddress = address;\n}\n\nvoid RHGenericDriver::setHeaderTo(uint8_t to) {\n _txHeaderTo = to;\n}\n\nvoid RHGenericDriver::setHeaderFrom(uint8_t from) {\n _txHeaderFrom = from;\n}\n\nvoid RHGenericDriver::setHeaderId(uint8_t id) {\n _txHeaderId = id;\n}\n\nvoid RHGenericDriver::setHeaderFlags(uint8_t set, uint8_t clear) {\n _txHeaderFlags &= ~clear;\n _txHeaderFlags |= set;\n}\n\nuint8_t RHGenericDriver::headerTo() {\n return _rxHeaderTo;\n}\n\nuint8_t RHGenericDriver::headerFrom() {\n return _rxHeaderFrom;\n}\n\nuint8_t RHGenericDriver::headerId() {\n return _rxHeaderId;\n}\n\nuint8_t RHGenericDriver::headerFlags() {\n return _rxHeaderFlags;\n}\n\nint8_t RHGenericDriver::lastRssi() {\n return _lastRssi;\n}\n\nRHGenericDriver::RHMode RHGenericDriver::mode() {\n return _mode;\n}\n\nvoid RHGenericDriver::setMode(RHMode mode) {\n _mode = mode;\n}\n\nbool RHGenericDriver::sleep() {\n return false;\n}\n\n// Diagnostic help\nvoid RHGenericDriver::printBuffer(const char* prompt, const uint8_t* buf, uint8_t len) {\n uint8_t i;\n\n #ifdef RH_HAVE_SERIAL\n Serial.println(prompt);\n for (i = 0; i < len; i++) {\n if (i % 16 == 15) {\n Serial.println(buf[i], HEX);\n } else {\n Serial.print(buf[i], HEX);\n Serial.print(' ');\n }\n }\n Serial.println(\"\");\n #endif\n}\n\nuint16_t RHGenericDriver::rxBad() {\n return _rxBad;\n}\n\nuint16_t RHGenericDriver::rxGood() {\n return _rxGood;\n}\n\nuint16_t RHGenericDriver::txGood() {\n return _txGood;\n}\n\n#if (RH_PLATFORM == RH_PLATFORM_ARDUINO) && defined(RH_PLATFORM_ATTINY)\n// Tinycore does not have __cxa_pure_virtual, so without this we\n// get linking complaints from the default code generated for pure virtual functions\nextern \"C\" void __cxa_pure_virtual() {\n while (1);\n}\n#endif\n" }, { filename: "src/RHGenericDriver.h", code: "// RHGenericDriver.h\n// Author: Mike McCauley (mikem@airspayce.com)\n// Copyright (C) 2014 Mike McCauley\n// $Id: RHGenericDriver.h,v 1.16 2015/01/02 21:38:24 mikem Exp $\n\n#ifndef RHGenericDriver_h\n#define RHGenericDriver_h\n\n#include \"RadioHead.h\"\n\n// Defines bits of the FLAGS header reserved for use by the RadioHead library and\n// the flags available for use by applications\n#define RH_FLAGS_RESERVED 0xf0\n#define RH_FLAGS_APPLICATION_SPECIFIC 0x0f\n#define RH_FLAGS_NONE 0\n\n/////////////////////////////////////////////////////////////////////\n/// \\class RHGenericDriver RHGenericDriver.h \n/// \\brief Abstract base class for a RadioHead driver.\n///\n/// This class defines the functions that must be provided by any RadioHead driver.\n/// Different types of driver will implement all the abstract functions, and will perhaps override\n/// other functions in this subclass, or perhaps add new functions specifically required by that driver.\n/// Do not directly instantiate this class: it is only to be subclassed by driver classes.\n///\n/// Subclasses are expected to implement a half-duplex, unreliable, error checked, unaddressed packet transport.\n/// They are expected to carry a message payload with an appropriate maximum length for the transport hardware\n/// and to also carry unaltered 4 message headers: TO, FROM, ID, FLAGS\n///\n/// \\par Headers\n///\n/// Each message sent and received by a RadioHead driver includes 4 headers:\n/// -TO The node address that the message is being sent to (broadcast RH_BROADCAST_ADDRESS (255) is permitted)\n/// -FROM The node address of the sending node\n/// -ID A message ID, distinct (over short time scales) for each message sent by a particilar node\n/// -FLAGS A bitmask of flags. The most significant 4 bits are reserved for use by RadioHead. The least\n/// significant 4 bits are reserved for applications.\nclass RHGenericDriver {\n public:\n /// \\brief Defines different operating modes for the transport hardware\n ///\n /// These are the different values that can be adopted by the _mode variable and\n /// returned by the mode() member function,\n typedef enum {\n RHModeInitialising = 0, ///< Transport is initialising. Initial default value until init() is called..\n RHModeSleep, ///< Transport hardware is in low power sleep mode (if supported)\n RHModeIdle, ///< Transport is idle.\n RHModeTx, ///< Transport is in the process of transmitting a message.\n RHModeRx ///< Transport is in the process of receiving a message.\n } RHMode;\n\n /// Constructor\n RHGenericDriver();\n\n /// Initialise the Driver transport hardware and software.\n /// Make sure the Driver is properly configured before calling init().\n /// \\return true if initialisation succeeded.\n virtual bool init();\n\n /// Tests whether a new message is available\n /// from the Driver.\n /// On most drivers, if there is an uncollected received message, and there is no message\n /// currently bing transmitted, this will also put the Driver into RHModeRx mode until\n /// a message is actually received by the transport, when it will be returned to RHModeIdle.\n /// This can be called multiple times in a timeout loop.\n /// \\return true if a new, complete, error-free uncollected message is available to be retreived by recv().\n virtual bool available() = 0;\n //virtual bool available(){};\n\n /// Turns the receiver on if it not already on.\n /// If there is a valid message available, copy it to buf and return true\n /// else return false.\n /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).\n /// You should be sure to call this function frequently enough to not miss any messages\n /// It is recommended that you call it in your main loop.\n /// \\param[in] buf Location to copy the received message\n /// \\param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.\n /// \\return true if a valid message was copied to buf\n virtual bool recv(uint8_t* buf, uint8_t* len) = 0;\n //virtual bool recv(uint8_t* buf, uint8_t* len){};\n\n /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().\n /// Then loads a message into the transmitter and starts the transmitter. Note that a message length\n /// of 0 is NOT permitted. If the message is too long for the underlying radio technology, send() will\n /// return false and will not send the message.\n /// \\param[in] data Array of data to be sent\n /// \\param[in] len Number of bytes of data to send (> 0)\n /// \\return true if the message length was valid and it was correctly queued for transmit\n virtual bool send(uint8_t* data, uint8_t len) = 0;\n //virtual bool send(uint8_t* data, uint8_t len){};\n\n /// Returns the maximum message length\n /// available in this Driver.\n /// \\return The maximum legal message length\n virtual uint8_t maxMessageLength() = 0;\n //virtual uint8_t maxMessageLength(){};\n\n /// Starts the receiver and blocks until a valid received\n /// message is available.\n virtual void waitAvailable();\n\n /// Blocks until the transmitter\n /// is no longer transmitting.\n virtual bool waitPacketSent();\n\n /// Blocks until the transmitter is no longer transmitting.\n /// or until the timeout occuers, whichever happens first\n /// \\param[in] timeout Maximum time to wait in milliseconds.\n /// \\return true if the RF22 completed transmission within the timeout period. False if it timed out.\n virtual bool waitPacketSent(uint16_t timeout);\n\n /// Starts the receiver and blocks until a received message is available or a timeout\n /// \\param[in] timeout Maximum time to wait in milliseconds.\n /// \\return true if a message is available\n virtual bool waitAvailableTimeout(uint16_t timeout);\n\n /// Sets the address of this node. Defaults to 0xFF. Subclasses or the user may want to change this.\n /// This will be used to test the adddress in incoming messages. In non-promiscuous mode,\n /// only messages with a TO header the same as thisAddress or the broadcast addess (0xFF) will be accepted.\n /// In promiscuous mode, all messages will be accepted regardless of the TO header.\n /// In a conventional multinode system, all nodes will have a unique address\n /// (which you could store in EEPROM).\n /// You would normally set the header FROM address to be the same as thisAddress (though you dont have to,\n /// allowing the possibilty of address spoofing).\n /// \\param[in] thisAddress The address of this node.\n virtual void setThisAddress(uint8_t thisAddress);\n\n /// Sets the TO header to be sent in all subsequent messages\n /// \\param[in] to The new TO header value\n virtual void setHeaderTo(uint8_t to);\n\n /// Sets the FROM header to be sent in all subsequent messages\n /// \\param[in] from The new FROM header value\n virtual void setHeaderFrom(uint8_t from);\n\n /// Sets the ID header to be sent in all subsequent messages\n /// \\param[in] id The new ID header value\n virtual void setHeaderId(uint8_t id);\n\n /// Sets and clears bits in the FLAGS header to be sent in all subsequent messages\n /// First it clears he FLAGS according to the clear argument, then sets the flags according to the\n /// set argument. The default for clear always clears the application specific flags.\n /// \\param[in] set bitmask of bits to be set. Flags are cleared with the clear mask before being set.\n /// \\param[in] clear bitmask of flags to clear. Defaults to RH_FLAGS_APPLICATION_SPECIFIC\n /// which clears the application specific flags, resulting in new application specific flags\n /// identical to the set.\n virtual void setHeaderFlags(uint8_t set, uint8_t clear = RH_FLAGS_APPLICATION_SPECIFIC);\n\n /// Tells the receiver to accept messages with any TO address, not just messages\n /// addressed to thisAddress or the broadcast address\n /// \\param[in] promiscuous true if you wish to receive messages with any TO address\n virtual void setPromiscuous(bool promiscuous);\n\n /// Returns the TO header of the last received message\n /// \\return The TO header\n virtual uint8_t headerTo();\n\n /// Returns the FROM header of the last received message\n /// \\return The FROM header\n virtual uint8_t headerFrom();\n\n /// Returns the ID header of the last received message\n /// \\return The ID header\n virtual uint8_t headerId();\n\n /// Returns the FLAGS header of the last received message\n /// \\return The FLAGS header\n virtual uint8_t headerFlags();\n\n /// Returns the most recent RSSI (Receiver Signal Strength Indicator).\n /// Usually it is the RSSI of the last received message, which is measured when the preamble is received.\n /// If you called readRssi() more recently, it will return that more recent value.\n /// \\return The most recent RSSI measurement in dBm.\n int8_t lastRssi();\n\n /// Returns the operating mode of the library.\n /// \\return the current mode, one of RF69_MODE_*\n RHMode mode();\n\n /// Sets the operating mode of the transport.\n void setMode(RHMode mode);\n\n /// Sets the transport hardware into low-power sleep mode\n /// (if supported). May be overridden by specific drivers to initialte sleep mode.\n /// If successful, the transport will stay in sleep mode until woken by\n /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc)\n /// \\return true if sleep mode is supported by transport hardware and the RadioHead driver, and if sleep mode\n /// was successfully entered. If sleep mode is not suported, return false.\n virtual bool sleep();\n\n /// Prints a data buffer in HEX.\n /// For diagnostic use\n /// \\param[in] prompt string to preface the print\n /// \\param[in] buf Location of the buffer to print\n /// \\param[in] len Length of the buffer in octets.\n static void printBuffer(const char* prompt, const uint8_t* buf, uint8_t len);\n\n /// Returns the count of the number of bad received packets (ie packets with bad lengths, checksum etc)\n /// which were rejected and not delivered to the application.\n /// Caution: not all drivers can correctly report this count. Some underlying hardware only report\n /// good packets.\n /// \\return The number of bad packets received.\n uint16_t rxBad();\n\n /// Returns the count of the number of\n /// good received packets\n /// \\return The number of good packets received.\n uint16_t rxGood();\n\n /// Returns the count of the number of\n /// packets successfully transmitted (though not necessarily received by the destination)\n /// \\return The number of packets successfully transmitted\n uint16_t txGood();\n\n protected:\n\n /// The current transport operating mode\n volatile RHMode _mode;\n\n /// This node id\n uint8_t _thisAddress;\n\n /// Whether the transport is in promiscuous mode\n bool _promiscuous;\n\n /// TO header in the last received mesasge\n volatile uint8_t _rxHeaderTo;\n\n /// FROM header in the last received mesasge\n volatile uint8_t _rxHeaderFrom;\n\n /// ID header in the last received mesasge\n volatile uint8_t _rxHeaderId;\n\n /// FLAGS header in the last received mesasge\n volatile uint8_t _rxHeaderFlags;\n\n /// TO header to send in all messages\n uint8_t _txHeaderTo;\n\n /// FROM header to send in all messages\n uint8_t _txHeaderFrom;\n\n /// ID header to send in all messages\n uint8_t _txHeaderId;\n\n /// FLAGS header to send in all messages\n uint8_t _txHeaderFlags;\n\n /// The value of the last received RSSI value, in some transport specific units\n volatile int8_t _lastRssi;\n\n /// Count of the number of bad messages (eg bad checksum etc) received\n volatile uint16_t _rxBad;\n\n /// Count of the number of successfully transmitted messaged\n volatile uint16_t _rxGood;\n\n /// Count of the number of bad messages (correct checksum etc) received\n volatile uint16_t _txGood;\n\n private:\n\n};\n\n\n#endif\n" }, { filename: "src/RHUartDriver.cpp", code: "#include \"RHUartDriver.h\"\n\ntemplate \nRHUartDriver::RHUartDriver(T& ss)\n :\n _ss(ss) {\n}\n\ntemplate \nbool RHUartDriver::init() {\n _ss.begin(57600);\n // _ss.listen();\n\n return true;\n}\n\ntemplate \nuint8_t RHUartDriver::uartAvailable(void) {\n return _ss.available();\n}\n\ntemplate \nuint8_t RHUartDriver::uartRead(void) {\n return _ss.read();\n}\n\ntemplate \nvoid RHUartDriver::uartTx(uint8_t reg, uint8_t* src, uint8_t len) {\n _ss.write('W');\n _ss.write(reg);\n _ss.write(len);\n for (int i = 0; i < len; i ++) {\n _ss.write(*(src + i));\n }\n}\n\ntemplate \nvoid RHUartDriver::uartRx(uint8_t reg, uint8_t* dest, uint8_t len) {\n _ss.write('R');\n _ss.write(reg);\n _ss.write(len);\n\n unsigned long timerStart, timerEnd;\n int i = 0;\n timerStart = millis();\n while (1) {\n if (_ss.available()) {\n *(dest + i) = _ss.read();\n i ++;\n if (i >= len) {\n break;\n }\n }\n\n timerEnd = millis();\n if (timerEnd - timerStart > 1000 * DEFAULT_TIMEOUT) {\n break;\n }\n }\n}\n\ntemplate \nuint8_t RHUartDriver::read(uint8_t reg) {\n uint8_t val = 0;\n uartRx(reg & ~RH_WRITE_MASK, &val, 1);\n return val;\n}\n\ntemplate \nvoid RHUartDriver::write(uint8_t reg, uint8_t val) {\n uartTx(reg | RH_WRITE_MASK, &val, 1);\n}\n\ntemplate \nvoid RHUartDriver::burstRead(uint8_t reg, uint8_t* dest, uint8_t len) {\n uartRx(reg & ~RH_WRITE_MASK, dest, len);\n}\n\ntemplate \nvoid RHUartDriver::burstWrite(uint8_t reg, uint8_t* src, uint8_t len) {\n uartTx(reg | RH_WRITE_MASK, src, len);\n}\n\n\n#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE\n template class RHUartDriver;\n#endif\ntemplate class RHUartDriver;\n\n#ifdef __AVR__\n #include \n template class RHUartDriver;\n#endif" }, { filename: "src/RHUartDriver.h", code: "/*\n RHUartDriver.h\n A library for Grove - Lora 433MHz/470MHz RF or Grove - Lora 868MHz/915MHz RF\n\n Copyright (c) 2015 seeed technology inc.\n Website : www.seeed.cc\n Author : JY.W\n Modified Time: 2016-07-15\n\n The MIT License (MIT)\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in\n all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n THE SOFTWARE.\n*/\n\n#ifndef _RH_UART_Driver_H_\n#define _RH_UART_Driver_H_\n\n\n#include \n#include \"RHGenericDriver.h\"\n\n\n#define DEFAULT_TIMEOUT 3\n\n#define RH_WRITE_MASK 0x80\n\ntemplate\nclass RHUartDriver : public RHGenericDriver {\n public:\n\n RHUartDriver(T& ss);\n\n virtual bool init();\n\n uint8_t uartAvailable(void);\n\n uint8_t uartRead(void);\n\n // 'W' + 'Reg' + 'Len' + 'Data'\n void uartTx(uint8_t reg, uint8_t* src, uint8_t len);\n\n // 'R' + 'Reg' + 'Len'\n void uartRx(uint8_t reg, uint8_t* dest, uint8_t len);\n\n uint8_t read(uint8_t reg);\n\n void write(uint8_t reg, uint8_t val);\n\n void burstRead(uint8_t reg, uint8_t* dest, uint8_t len);\n\n void burstWrite(uint8_t reg, uint8_t* src, uint8_t len);\n\n protected:\n\n T& _ss;\n\n private:\n\n\n\n};\n\n#endif\n" }, { filename: "src/RH_RF95.cpp", code: "\n#include \"RH_RF95.h\"\n\n\n// These are indexed by the values of ModemConfigChoice\n// Stored in flash (program) memory to save SRAM\nPROGMEM static const ModemConfig MODEM_CONFIG_TABLE[] = {\n // 1d, 1e, 26\n { 0x72, 0x74, 0x00}, // Bw125Cr45Sf128 (the chip default)\n { 0x92, 0x74, 0x00}, // Bw500Cr45Sf128\n { 0x48, 0x94, 0x00}, // Bw31_25Cr48Sf512\n { 0x78, 0xc4, 0x00}, // Bw125Cr48Sf4096\n\n};\n\ntemplate \nRH_RF95::RH_RF95(T& ss)\n :\n RHUartDriver(ss),\n _rxBufValid(0) {\n}\n\ntemplate \nbool RH_RF95::init() {\n RHUartDriver::init();\n\n // Set sleep mode, so we can also set LORA mode:\n this->write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_SLEEP | RH_RF95_LONG_RANGE_MODE);\n delay(10); // Wait for sleep mode to take over from say, CAD\n\n // Check we are in sleep mode, with LORA set\n if (this->read(RH_RF95_REG_01_OP_MODE) != (RH_RF95_MODE_SLEEP | RH_RF95_LONG_RANGE_MODE)) {\n Serial.println(this->read(RH_RF95_REG_01_OP_MODE), HEX);\n return false; // No device present?\n }\n\n // Set up FIFO\n // We configure so that we can use the entire 256 byte FIFO for either receive\n // or transmit, but not both at the same time\n this->write(RH_RF95_REG_0E_FIFO_TX_BASE_ADDR, 0);\n this->write(RH_RF95_REG_0F_FIFO_RX_BASE_ADDR, 0);\n\n // Packet format is preamble + explicit-header + payload + crc\n // Explicit Header Mode\n // payload is TO + FROM + ID + FLAGS + message data\n // RX mode is implmented with RXCONTINUOUS\n // max message data length is 255 - 4 = 251 octets\n\n setModeIdle();\n\n // Set up default configuration\n // No Sync Words in LORA mode.\n setModemConfig(Bw125Cr45Sf128); // Radio default\n //setModemConfig(Bw125Cr48Sf4096); // slow and reliable?\n setPreambleLength(8); // Default is 8\n // An innocuous ISM frequency, same as RF22's\n //setFrequency(434.0);\n setFrequency(868.0);\n // Lowish power\n setTxPower(13);\n\n return true;\n}\n\n// C++ level interrupt handler for this instance\n// LORA is unusual in that it has several interrupt lines, and not a single, combined one.\n// On MiniWirelessLoRa, only one of the several interrupt lines (DI0) from the RFM95 is usefuly\n// connnected to the processor.\n// We use this to get RxDone and TxDone interrupts\n\ntemplate \nvoid RH_RF95::handleInterrupt() {\n // Read the interrupt register\n uint8_t irq_flags = this->read(RH_RF95_REG_12_IRQ_FLAGS);\n if (this->_mode == RHGenericDriver::RHModeRx && irq_flags & (RH_RF95_RX_TIMEOUT | RH_RF95_PAYLOAD_CRC_ERROR)) {\n this->_rxBad++;\n } else if (this->_mode == RHGenericDriver::RHModeRx && irq_flags & RH_RF95_RX_DONE) {\n // Have received a packet\n uint8_t len = this->read(RH_RF95_REG_13_RX_NB_BYTES);\n\n // Reset the fifo this->read ptr to the beginning of the packet\n this->write(RH_RF95_REG_0D_FIFO_ADDR_PTR, this->read(RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR));\n this->burstRead(RH_RF95_REG_00_FIFO, _buf, len);\n _bufLen = len;\n this->write(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags\n\n // Remember the RSSI of this packet\n // this is according to the doc, but is it really correct?\n // weakest receiveable signals are reported RSSI at about -66\n this->_lastRssi = this->read(RH_RF95_REG_1A_PKT_RSSI_VALUE) - 137;\n\n // We have received a message.\n validateRxBuf();\n if (_rxBufValid) {\n setModeIdle(); // Got one\n }\n } else if (this->_mode == RHGenericDriver::RHModeTx && irq_flags & RH_RF95_TX_DONE) {\n this->_txGood++;\n setModeIdle();\n }\n\n this->write(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags\n}\n\n// Check whether the latest received message is complete and uncorrupted\n\ntemplate \nvoid RH_RF95::validateRxBuf() {\n if (_bufLen < 4) {\n return; // Too short to be a real message\n }\n\n // Extract the 4 headers\n this->_rxHeaderTo = _buf[0];\n this->_rxHeaderFrom = _buf[1];\n this->_rxHeaderId = _buf[2];\n this->_rxHeaderFlags = _buf[3];\n\n if (this->_promiscuous || this->_rxHeaderTo == this->_thisAddress || this->_rxHeaderTo == RH_BROADCAST_ADDRESS) {\n this->_rxGood++;\n _rxBufValid = true;\n }\n}\n\n\ntemplate \nbool RH_RF95::available() {\n if (this->uartAvailable()) {\n if (this->uartRead() == 'I') {\n handleInterrupt();\n }\n }\n\n if (this->_mode == RHGenericDriver::RHModeTx) {\n return false;\n }\n setModeRx();\n\n return _rxBufValid; // Will be set by the interrupt handler when a good message is received\n}\n\ntemplate \nvoid RH_RF95::clearRxBuf() {\n _rxBufValid = false;\n _bufLen = 0;\n}\n\n\ntemplate \nbool RH_RF95::recv(uint8_t* buf, uint8_t* len) {\n if (!available()) {\n return false;\n }\n if (buf && len) {\n // Skip the 4 headers that are at the beginning of the rxBuf\n if (*len > _bufLen - RH_RF95_HEADER_LEN) {\n *len = _bufLen - RH_RF95_HEADER_LEN;\n }\n memcpy(buf, _buf + RH_RF95_HEADER_LEN, *len);\n }\n clearRxBuf(); // This message accepted and cleared\n return true;\n}\n\n\ntemplate \nbool RH_RF95::send(uint8_t* data, uint8_t len) {\n if (len > RH_RF95_MAX_MESSAGE_LEN) {\n return false;\n }\n\n this->waitPacketSent(); // Make sure we dont interrupt an outgoing message\n setModeIdle();\n\n // Position at the beginning of the FIFO\n this->write(RH_RF95_REG_0D_FIFO_ADDR_PTR, 0);\n\n // The headers\n this->write(RH_RF95_REG_00_FIFO, this->_txHeaderTo);\n this->write(RH_RF95_REG_00_FIFO, this->_txHeaderFrom);\n this->write(RH_RF95_REG_00_FIFO, this->_txHeaderId);\n this->write(RH_RF95_REG_00_FIFO, this->_txHeaderFlags);\n\n // The message data\n this->burstWrite(RH_RF95_REG_00_FIFO, data, len);\n this->write(RH_RF95_REG_22_PAYLOAD_LENGTH, len + RH_RF95_HEADER_LEN);\n\n setModeTx(); // Start the transmitter\n // when Tx is done, interruptHandler will fire and radio mode will return to STANDBY\n\n //this->write(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags\n return true;\n}\n\n\ntemplate \nbool RH_RF95::printRegisters() {\n #ifdef RH_HAVE_SERIAL\n uint8_t registers[] = { 0x01, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x014, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27};\n\n uint8_t i;\n for (i = 0; i < sizeof(registers); i++) {\n Serial.print(registers[i], HEX);\n Serial.print(\": \");\n Serial.println(this->read(registers[i]), HEX);\n }\n #endif\n return true;\n}\n\n\ntemplate \nuint8_t RH_RF95::maxMessageLength() {\n return RH_RF95_MAX_MESSAGE_LEN;\n}\n\n\ntemplate \nbool RH_RF95::setFrequency(float centre) {\n // Frf = FRF / FSTEP\n uint32_t frf = (centre * 1000000.0) / RH_RF95_FSTEP;\n this->write(RH_RF95_REG_06_FRF_MSB, (frf >> 16) & 0xff);\n this->write(RH_RF95_REG_07_FRF_MID, (frf >> 8) & 0xff);\n this->write(RH_RF95_REG_08_FRF_LSB, frf & 0xff);\n\n return true;\n}\n\n\ntemplate \nvoid RH_RF95::setModeIdle() {\n if (this->_mode != RHGenericDriver::RHModeIdle) {\n this->write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_STDBY);\n this->_mode = RHGenericDriver::RHModeIdle;\n }\n}\n\n\ntemplate \nbool RH_RF95::sleep() {\n if (this->_mode != RHGenericDriver::RHModeSleep) {\n this->write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_SLEEP);\n this->_mode = RHGenericDriver::RHModeSleep;\n }\n return true;\n}\n\n\ntemplate \nvoid RH_RF95::setModeRx() {\n if (this->_mode != RHGenericDriver::RHModeRx) {\n this->write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_RXCONTINUOUS);\n this->write(RH_RF95_REG_40_DIO_MAPPING1, 0x00); // Interrupt on RxDone\n this->_mode = RHGenericDriver::RHModeRx;\n }\n}\n\n\ntemplate \nvoid RH_RF95::setModeTx() {\n if (this->_mode != RHGenericDriver::RHModeTx) {\n this->write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_TX);\n this->write(RH_RF95_REG_40_DIO_MAPPING1, 0x40); // Interrupt on TxDone\n this->_mode = RHGenericDriver::RHModeTx;\n }\n}\n\n\ntemplate \nvoid RH_RF95::setTxPower(int8_t power, bool useRFO) {\n // Sigh, different behaviours depending on whther the module use PA_BOOST or the RFO pin\n // for the transmitter output\n if (useRFO) {\n if (power > 14) {\n power = 14;\n }\n if (power < -1) {\n power = -1;\n }\n this->write(RH_RF95_REG_09_PA_CONFIG, RH_RF95_MAX_POWER | (power + 1));\n } else {\n if (power > 23) {\n power = 23;\n }\n if (power < 5) {\n power = 5;\n }\n\n // For RH_RF95_PA_DAC_ENABLE, manual says '+20dBm on PA_BOOST when OutputPower=0xf'\n // RH_RF95_PA_DAC_ENABLE actually adds about 3dBm to all power levels. We will us it\n // for 21 and 23dBm\n if (power > 20) {\n this->write(RH_RF95_REG_4D_PA_DAC, RH_RF95_PA_DAC_ENABLE);\n power -= 3;\n } else {\n this->write(RH_RF95_REG_4D_PA_DAC, RH_RF95_PA_DAC_DISABLE);\n }\n\n // RFM95/96/97/98 does not have RFO pins connected to anything. Only PA_BOOST\n // pin is connected, so must use PA_BOOST\n // Pout = 2 + OutputPower.\n // The documentation is pretty confusing on this topic: PaSelect says the max power is 20dBm,\n // but OutputPower claims it would be 17dBm.\n // My measurements show 20dBm is correct\n this->write(RH_RF95_REG_09_PA_CONFIG, RH_RF95_PA_SELECT | (power - 5));\n }\n}\n\n// Sets registers from a canned modem configuration structure\ntemplate \nvoid RH_RF95::setModemRegisters(const ModemConfig* config) {\n this->write(RH_RF95_REG_1D_MODEM_CONFIG1, config->reg_1d);\n this->write(RH_RF95_REG_1E_MODEM_CONFIG2, config->reg_1e);\n this->write(RH_RF95_REG_26_MODEM_CONFIG3, config->reg_26);\n}\n\n// Set one of the canned FSK Modem configs\n// Returns true if its a valid choice\ntemplate \nbool RH_RF95::setModemConfig(ModemConfigChoice index) {\n if (index > (signed int)(sizeof(MODEM_CONFIG_TABLE) / sizeof(ModemConfig))) {\n return false;\n }\n\n ModemConfig cfg;\n memcpy_P(&cfg, &MODEM_CONFIG_TABLE[index], sizeof(ModemConfig));\n setModemRegisters(&cfg);\n\n return true;\n}\n\ntemplate \nvoid RH_RF95::setPreambleLength(uint16_t bytes) {\n this->write(RH_RF95_REG_20_PREAMBLE_MSB, bytes >> 8);\n this->write(RH_RF95_REG_21_PREAMBLE_LSB, bytes & 0xff);\n}\n\n#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE\n template class RH_RF95;\n#endif\ntemplate class RH_RF95;\n\n#ifdef __AVR__\n #include \n template class RH_RF95;\n#endif" }, { filename: "src/RH_RF95.h", code: "\n\n#ifndef RH_RF95_h\n#define RH_RF95_h\n\n\n#include \"RHUartDriver.h\"\n\n\n#define RH_HAVE_SERIAL\n\n// Max number of octets the LORA Rx/Tx FIFO can hold\n#define RH_RF95_FIFO_SIZE 255\n\n// This is the maximum number of bytes that can be carried by the LORA.\n// We use some for headers, keeping fewer for RadioHead messages\n#define RH_RF95_MAX_PAYLOAD_LEN RH_RF95_FIFO_SIZE\n\n// The length of the headers we add.\n// The headers are inside the LORA's payload\n#define RH_RF95_HEADER_LEN 4\n\n// This is the maximum message length that can be supported by this driver.\n// Can be pre-defined to a smaller size (to save SRAM) prior to including this header\n// Here we allow for 1 byte message length, 4 bytes headers, user data and 2 bytes of FCS\n#ifndef RH_RF95_MAX_MESSAGE_LEN\n #define RH_RF95_MAX_MESSAGE_LEN (RH_RF95_MAX_PAYLOAD_LEN - RH_RF95_HEADER_LEN)\n#endif\n\n// The crystal oscillator frequency of the module\n#define RH_RF95_FXOSC 32000000.0\n\n// The Frequency Synthesizer step = RH_RF95_FXOSC / 2^^19\n#define RH_RF95_FSTEP (RH_RF95_FXOSC / 524288)\n\n\n// Register names (LoRa Mode, from table 85)\n#define RH_RF95_REG_00_FIFO 0x00\n#define RH_RF95_REG_01_OP_MODE 0x01\n#define RH_RF95_REG_02_RESERVED 0x02\n#define RH_RF95_REG_03_RESERVED 0x03\n#define RH_RF95_REG_04_RESERVED 0x04\n#define RH_RF95_REG_05_RESERVED 0x05\n#define RH_RF95_REG_06_FRF_MSB 0x06\n#define RH_RF95_REG_07_FRF_MID 0x07\n#define RH_RF95_REG_08_FRF_LSB 0x08\n#define RH_RF95_REG_09_PA_CONFIG 0x09\n#define RH_RF95_REG_0A_PA_RAMP 0x0a\n#define RH_RF95_REG_0B_OCP 0x0b\n#define RH_RF95_REG_0C_LNA 0x0c\n#define RH_RF95_REG_0D_FIFO_ADDR_PTR 0x0d\n#define RH_RF95_REG_0E_FIFO_TX_BASE_ADDR 0x0e\n#define RH_RF95_REG_0F_FIFO_RX_BASE_ADDR 0x0f\n#define RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR 0x10\n#define RH_RF95_REG_11_IRQ_FLAGS_MASK 0x11\n#define RH_RF95_REG_12_IRQ_FLAGS 0x12\n#define RH_RF95_REG_13_RX_NB_BYTES 0x13\n#define RH_RF95_REG_14_RX_HEADER_CNT_VALUE_MSB 0x14\n#define RH_RF95_REG_15_RX_HEADER_CNT_VALUE_LSB 0x15\n#define RH_RF95_REG_16_RX_PACKET_CNT_VALUE_MSB 0x16\n#define RH_RF95_REG_17_RX_PACKET_CNT_VALUE_LSB 0x17\n#define RH_RF95_REG_18_MODEM_STAT 0x18\n#define RH_RF95_REG_19_PKT_SNR_VALUE 0x19\n#define RH_RF95_REG_1A_PKT_RSSI_VALUE 0x1a\n#define RH_RF95_REG_1B_RSSI_VALUE 0x1b\n#define RH_RF95_REG_1C_HOP_CHANNEL 0x1c\n#define RH_RF95_REG_1D_MODEM_CONFIG1 0x1d\n#define RH_RF95_REG_1E_MODEM_CONFIG2 0x1e\n#define RH_RF95_REG_1F_SYMB_TIMEOUT_LSB 0x1f\n#define RH_RF95_REG_20_PREAMBLE_MSB 0x20\n#define RH_RF95_REG_21_PREAMBLE_LSB 0x21\n#define RH_RF95_REG_22_PAYLOAD_LENGTH 0x22\n#define RH_RF95_REG_23_MAX_PAYLOAD_LENGTH 0x23\n#define RH_RF95_REG_24_HOP_PERIOD 0x24\n#define RH_RF95_REG_25_FIFO_RX_BYTE_ADDR 0x25\n#define RH_RF95_REG_26_MODEM_CONFIG3 0x26\n\n#define RH_RF95_REG_40_DIO_MAPPING1 0x40\n#define RH_RF95_REG_41_DIO_MAPPING2 0x41\n#define RH_RF95_REG_42_VERSION 0x42\n\n#define RH_RF95_REG_4B_TCXO 0x4b\n#define RH_RF95_REG_4D_PA_DAC 0x4d\n#define RH_RF95_REG_5B_FORMER_TEMP 0x5b\n#define RH_RF95_REG_61_AGC_REF 0x61\n#define RH_RF95_REG_62_AGC_THRESH1 0x62\n#define RH_RF95_REG_63_AGC_THRESH2 0x63\n#define RH_RF95_REG_64_AGC_THRESH3 0x64\n\n// RH_RF95_REG_01_OP_MODE 0x01\n#define RH_RF95_LONG_RANGE_MODE 0x80\n#define RH_RF95_ACCESS_SHARED_REG 0x40\n#define RH_RF95_MODE 0x07\n#define RH_RF95_MODE_SLEEP 0x00\n#define RH_RF95_MODE_STDBY 0x01\n#define RH_RF95_MODE_FSTX 0x02\n#define RH_RF95_MODE_TX 0x03\n#define RH_RF95_MODE_FSRX 0x04\n#define RH_RF95_MODE_RXCONTINUOUS 0x05\n#define RH_RF95_MODE_RXSINGLE 0x06\n#define RH_RF95_MODE_CAD 0x07\n\n// RH_RF95_REG_09_PA_CONFIG 0x09\n#define RH_RF95_PA_SELECT 0x80\n#define RH_RF95_MAX_POWER 0x70\n#define RH_RF95_OUTPUT_POWER 0x0f\n\n// RH_RF95_REG_0A_PA_RAMP 0x0a\n#define RH_RF95_LOW_PN_TX_PLL_OFF 0x10\n#define RH_RF95_PA_RAMP 0x0f\n#define RH_RF95_PA_RAMP_3_4MS 0x00\n#define RH_RF95_PA_RAMP_2MS 0x01\n#define RH_RF95_PA_RAMP_1MS 0x02\n#define RH_RF95_PA_RAMP_500US 0x03\n#define RH_RF95_PA_RAMP_250US 0x0\n#define RH_RF95_PA_RAMP_125US 0x05\n#define RH_RF95_PA_RAMP_100US 0x06\n#define RH_RF95_PA_RAMP_62US 0x07\n#define RH_RF95_PA_RAMP_50US 0x08\n#define RH_RF95_PA_RAMP_40US 0x09\n#define RH_RF95_PA_RAMP_31US 0x0a\n#define RH_RF95_PA_RAMP_25US 0x0b\n#define RH_RF95_PA_RAMP_20US 0x0c\n#define RH_RF95_PA_RAMP_15US 0x0d\n#define RH_RF95_PA_RAMP_12US 0x0e\n#define RH_RF95_PA_RAMP_10US 0x0f\n\n// RH_RF95_REG_0B_OCP 0x0b\n#define RH_RF95_OCP_ON 0x20\n#define RH_RF95_OCP_TRIM 0x1f\n\n// RH_RF95_REG_0C_LNA 0x0c\n#define RH_RF95_LNA_GAIN 0xe0\n#define RH_RF95_LNA_BOOST 0x03\n#define RH_RF95_LNA_BOOST_DEFAULT 0x00\n#define RH_RF95_LNA_BOOST_150PC 0x11\n\n// RH_RF95_REG_11_IRQ_FLAGS_MASK 0x11\n#define RH_RF95_RX_TIMEOUT_MASK 0x80\n#define RH_RF95_RX_DONE_MASK 0x40\n#define RH_RF95_PAYLOAD_CRC_ERROR_MASK 0x20\n#define RH_RF95_VALID_HEADER_MASK 0x10\n#define RH_RF95_TX_DONE_MASK 0x08\n#define RH_RF95_CAD_DONE_MASK 0x04\n#define RH_RF95_FHSS_CHANGE_CHANNEL_MASK 0x02\n#define RH_RF95_CAD_DETECTED_MASK 0x01\n\n// RH_RF95_REG_12_IRQ_FLAGS 0x12\n#define RH_RF95_RX_TIMEOUT 0x80\n#define RH_RF95_RX_DONE 0x40\n#define RH_RF95_PAYLOAD_CRC_ERROR 0x20\n#define RH_RF95_VALID_HEADER 0x10\n#define RH_RF95_TX_DONE 0x08\n#define RH_RF95_CAD_DONE 0x04\n#define RH_RF95_FHSS_CHANGE_CHANNEL 0x02\n#define RH_RF95_CAD_DETECTED 0x01\n\n// RH_RF95_REG_18_MODEM_STAT 0x18\n#define RH_RF95_RX_CODING_RATE 0xe0\n#define RH_RF95_MODEM_STATUS_CLEAR 0x10\n#define RH_RF95_MODEM_STATUS_HEADER_INFO_VALID 0x08\n#define RH_RF95_MODEM_STATUS_RX_ONGOING 0x04\n#define RH_RF95_MODEM_STATUS_SIGNAL_SYNCHRONIZED 0x02\n#define RH_RF95_MODEM_STATUS_SIGNAL_DETECTED 0x01\n\n// RH_RF95_REG_1C_HOP_CHANNEL 0x1c\n#define RH_RF95_PLL_TIMEOUT 0x80\n#define RH_RF95_RX_PAYLOAD_CRC_IS_ON 0x40\n#define RH_RF95_FHSS_PRESENT_CHANNEL 0x3f\n\n// RH_RF95_REG_1D_MODEM_CONFIG1 0x1d\n#define RH_RF95_BW 0xc0\n#define RH_RF95_BW_125KHZ 0x00\n#define RH_RF95_BW_250KHZ 0x40\n#define RH_RF95_BW_500KHZ 0x80\n#define RH_RF95_BW_RESERVED 0xc0\n#define RH_RF95_CODING_RATE 0x38\n#define RH_RF95_CODING_RATE_4_5 0x00\n#define RH_RF95_CODING_RATE_4_6 0x08\n#define RH_RF95_CODING_RATE_4_7 0x10\n#define RH_RF95_CODING_RATE_4_8 0x18\n#define RH_RF95_IMPLICIT_HEADER_MODE_ON 0x04\n#define RH_RF95_RX_PAYLOAD_CRC_ON 0x02\n#define RH_RF95_LOW_DATA_RATE_OPTIMIZE 0x01\n\n// RH_RF95_REG_1E_MODEM_CONFIG2 0x1e\n#define RH_RF95_SPREADING_FACTOR 0xf0\n#define RH_RF95_SPREADING_FACTOR_64CPS 0x60\n#define RH_RF95_SPREADING_FACTOR_128CPS 0x70\n#define RH_RF95_SPREADING_FACTOR_256CPS 0x80\n#define RH_RF95_SPREADING_FACTOR_512CPS 0x90\n#define RH_RF95_SPREADING_FACTOR_1024CPS 0xa0\n#define RH_RF95_SPREADING_FACTOR_2048CPS 0xb0\n#define RH_RF95_SPREADING_FACTOR_4096CPS 0xc0\n#define RH_RF95_TX_CONTINUOUS_MOE 0x08\n#define RH_RF95_AGC_AUTO_ON 0x04\n#define RH_RF95_SYM_TIMEOUT_MSB 0x03\n\n// RH_RF95_REG_4D_PA_DAC 0x4d\n#define RH_RF95_PA_DAC_DISABLE 0x04\n#define RH_RF95_PA_DAC_ENABLE 0x07\n\n/// Defines register values for a set of modem configuration registers\n/// that can be passed to setModemRegisters() if none of the choices in\n/// ModemConfigChoice suit your need setModemRegisters() writes the\n/// register values from this structure to the appropriate registers\n/// to set the desired spreading factor, coding rate and bandwidth\ntypedef struct {\n uint8_t reg_1d; ///< Value for register RH_RF95_REG_1D_MODEM_CONFIG1\n uint8_t reg_1e; ///< Value for register RH_RF95_REG_1E_MODEM_CONFIG2\n uint8_t reg_26; ///< Value for register RH_RF95_REG_26_MODEM_CONFIG3\n} ModemConfig;\n\ntemplate\nclass RH_RF95 : public RHUartDriver {\n public:\n\n\n /// Choices for setModemConfig() for a selected subset of common\n /// data rates. If you need another configuration,\n /// determine the necessary settings and call setModemRegisters() with your\n /// desired settings. It might be helpful to use the LoRa calculator mentioned in\n /// http://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf\n /// These are indexes into MODEM_CONFIG_TABLE. We strongly recommend you use these symbolic\n /// definitions and not their integer equivalents: its possible that new values will be\n /// introduced in later versions (though we will try to avoid it).\n typedef enum {\n Bw125Cr45Sf128 = 0,\t ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range\n Bw500Cr45Sf128,\t ///< Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range\n Bw31_25Cr48Sf512,\t ///< Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range\n Bw125Cr48Sf4096, ///< Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. Slow+long range\n } ModemConfigChoice;\n\n RH_RF95(T& ss);\n\n /// Initialise the Driver transport hardware and software.\n /// Make sure the Driver is properly configured before calling init().\n /// \\return true if initialisation succeeded.\n virtual bool init();\n\n /// Prints the value of all chip registers\n /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform\n /// For debugging purposes only.\n /// \\return true on success\n bool printRegisters();\n\n /// Sets all the registered required to configure the data modem in the RF95/96/97/98, including the bandwidth,\n /// spreading factor etc. You can use this to configure the modem with custom configurations if none of the\n /// canned configurations in ModemConfigChoice suit you.\n /// \\param[in] config A ModemConfig structure containing values for the modem configuration registers.\n void setModemRegisters(const ModemConfig* config);\n\n /// Select one of the predefined modem configurations. If you need a modem configuration not provided\n /// here, use setModemRegisters() with your own ModemConfig.\n /// \\param[in] index The configuration choice.\n /// \\return true if index is a valid choice.\n bool setModemConfig(ModemConfigChoice index);\n\n /// Tests whether a new message is available\n /// from the Driver.\n /// On most drivers, this will also put the Driver into RHModeRx mode until\n /// a message is actually received by the transport, when it wil be returned to RHModeIdle.\n /// This can be called multiple times in a timeout loop\n /// \\return true if a new, complete, error-free uncollected message is available to be retreived by recv()\n virtual bool available();\n\n /// Turns the receiver on if it not already on.\n /// If there is a valid message available, copy it to buf and return true\n /// else return false.\n /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).\n /// You should be sure to call this function frequently enough to not miss any messages\n /// It is recommended that you call it in your main loop.\n /// \\param[in] buf Location to copy the received message\n /// \\param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.\n /// \\return true if a valid message was copied to buf\n virtual bool recv(uint8_t* buf, uint8_t* len);\n\n /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().\n /// Then loads a message into the transmitter and starts the transmitter. Note that a message length\n /// of 0 is permitted.\n /// \\param[in] data Array of data to be sent\n /// \\param[in] len Number of bytes of data to send\n /// \\return true if the message length was valid and it was correctly queued for transmit\n virtual bool send(uint8_t* data, uint8_t len);\n\n /// Sets the length of the preamble\n /// in bytes.\n /// Caution: this should be set to the same\n /// value on all nodes in your network. Default is 8.\n /// Sets the message preamble length in RH_RF95_REG_??_PREAMBLE_?SB\n /// \\param[in] bytes Preamble length in bytes.\n void setPreambleLength(uint16_t bytes);\n\n /// Returns the maximum message length\n /// available in this Driver.\n /// \\return The maximum legal message length\n virtual uint8_t maxMessageLength();\n\n /// Sets the transmitter and receiver\n /// centre frequency.\n /// \\param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution: RFM95/96/97/98 comes in several\n /// different frequency ranges, and setting a frequency outside that range of your radio will probably not work\n /// \\return true if the selected frquency centre is within range\n bool setFrequency(float centre);\n\n /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running,\n /// disables them.\n void setModeIdle();\n\n /// If current mode is Tx or Idle, changes it to Rx.\n /// Starts the receiver in the RF95/96/97/98.\n void setModeRx();\n\n /// If current mode is Rx or Idle, changes it to Rx. F\n /// Starts the transmitter in the RF95/96/97/98.\n void setModeTx();\n\n /// Sets the transmitter power output level, and configures the transmitter pin.\n /// Be a good neighbour and set the lowest power level you need.\n /// Some SX1276/77/78/79 and compatible modules (such as RFM95/96/97/98)\n /// use the PA_BOOST transmitter pin for high power output (and optionally the PA_DAC)\n /// while some (such as the Modtronix inAir4 and inAir9)\n /// use the RFO transmitter pin for lower power but higher efficiency.\n /// You must set the appropriate power level and useRFO argument for your module.\n /// Check with your module manufacturer which transmtter pin is used on your module\n /// to ensure you are setting useRFO correctly.\n /// Failure to do so will result in very low\n /// transmitter power output.\n /// Caution: legal power limits may apply in certain countries.\n /// After init(), the power will be set to 13dBm, with useRFO false (ie PA_BOOST enabled).\n /// \\param[in] power Transmitter power level in dBm. For RFM95/96/97/98 LORA with useRFO false,\n /// valid values are from +5 to +23.\n /// For Modtronix inAir4 and inAir9 with useRFO true (ie RFO pins in use),\n /// valid values are from -1 to 14.\n /// \\param[in] useRFO If true, enables the use of the RFO transmitter pins instead of\n /// the PA_BOOST pin (false). Choose the correct setting for your module.\n void setTxPower(int8_t power, bool useRFO = false);\n\n /// Sets the radio into low-power sleep mode.\n /// If successful, the transport will stay in sleep mode until woken by\n /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc)\n /// Caution: there is a time penalty as the radio takes a finite time to wake from sleep mode.\n /// \\return true if sleep mode was successfully entered.\n virtual bool sleep();\n\n\n\n protected:\n /// This is a low level function to handle the interrupts for one instance of RH_RF95.\n /// Called automatically by isr*()\n /// Should not need to be called by user code.\n void handleInterrupt();\n\n /// Examine the revceive buffer to determine whether the message is for this node\n void validateRxBuf();\n\n /// Clear our local receive buffer\n void clearRxBuf();\n\n private:\n /// Number of octets in the buffer\n volatile uint8_t _bufLen;\n\n /// The receiver/transmitter buffer\n uint8_t _buf[RH_RF95_MAX_PAYLOAD_LEN];\n\n /// True when there is a valid message in the buffer\n volatile bool _rxBufValid;\n};\n\n/// @example rf95_client.pde\n/// @example rf95_server.pde\n/// @example rf95_reliable_datagram_client.pde\n/// @example rf95_reliable_datagram_server.pde\n\n#endif\n\n" }, { filename: "src/simulator.h", code: "// simulator.h\n// Lets Arduino RadioHead sketches run within a simulator on Linux as a single process\n// Copyright (C) 2014 Mike McCauley\n// $Id: simulator.h,v 1.4 2015/08/13 02:45:47 mikem Exp mikem $\n\n#ifndef simulator_h\n#define simulator_h\n\n#include \n#include \n#include \n#include \n\n// Equivalent types for common Arduino types like uint8_t are in stdint.h\n\n// Access to some globals\n// Command line args passed to the process.\nextern int _simulator_argc;\nextern char** _simulator_argv;\n\n// Definitions for various Arduino functions\nextern void delay(unsigned long ms);\nextern unsigned long millis();\nextern long random(long to);\nextern long random(long from, long to);\n\n// Equavalent to HardwareSerial in Arduino\n// but outputs to stdout\nclass SerialSimulator {\n public:\n#define DEC 10\n#define HEX 16\n#define OCT 8\n#define BIN 2\n\n // TODO: move these from being inlined\n void begin(int baud) {}\n\n size_t println(const char* s) {\n print(s);\n return printf(\"\\n\");\n }\n size_t print(const char* s) {\n return printf(\"%s\", s); // This style prevent warnings from [-Wformat-security]\n }\n size_t print(unsigned int n, int base = DEC) {\n if (base == DEC) {\n return printf(\"%d\", n);\n } else if (base == HEX) {\n return printf(\"%02x\", n);\n } else if (base == OCT) {\n return printf(\"%o\", n);\n }\n // TODO: BIN\n else {\n return 0;\n }\n }\n size_t print(char ch) {\n return printf(\"%c\", ch);\n }\n size_t println(char ch) {\n return printf(\"%c\\n\", ch);\n }\n size_t print(unsigned char ch, int base = DEC) {\n return print((unsigned int)ch, base);\n }\n size_t println(unsigned char ch, int base = DEC) {\n print((unsigned int)ch, base);\n return printf(\"\\n\");\n }\n\n};\n\n// Global instance of the Serial output\nextern SerialSimulator Serial;\n\n#endif\n" }] }; const extFacePanels = {}; const ExtHandler = { onLoad: function onLoad(app, target) { const that = this; if (!that.__workerSetupInstance) { that.__workerSetupInstance = that.workerSetup({ app }).then(() => { that.worker.remote.runExtension('onLoad', target.id); }); } }, onUnload: function onUnload(app) { this.__workerSetupInstance = null; this.worker.remote.runExtension('onUnload'); this.worker.dispose(); }, onConnect: function onConnect(app, device) { this.worker.remote.runExtension('onConnect', device.id); }, onDisconnect: function onDisconnect(app, device) { this.worker.remote.runExtension('onDisconnect', device.id); }, onStopAll: function onStopAll(app, device) { this.worker.remote.runExtension('onStopAll', device.id); }, beforeChangeUploadMode: function beforeChangeUploadMode(app, device) { return this.worker.remote.runExtension('beforeChangeUploadMode', device.id); }, beforeChangeDebugMode: function beforeChangeDebugMode(app, device) { return this.worker.remote.runExtension('beforeChangeDebugMode', device.id); }, afterChangeUploadMode: function afterChangeUploadMode(app, device) { this.worker.remote.runExtension('afterChangeUploadMode', device.id); }, afterChangeDebugMode: function afterChangeDebugMode(app, device) { this.worker.remote.runExtension('afterChangeDebugMode', device.id); }, onSelect: function onSelect(app, device) { if (!this.worker) { setTimeout(() => { this.onSelect(app, device); }, 200); return; } this.worker.remote.runExtension('onSelect', device.id); }, onUnselect: function onUnselect(app, device) { this.worker.remote.runExtension('onUnselect', device.id); }, beforeCodeUpload: function beforeCodeUpload(app, device) { this.worker.remote.runExtension('beforeCodeUpload', device.id); }, afterCodeUpload: function afterCodeUpload(app, device) { this.worker.remote.runExtension('afterCodeUpload', device.id); }, onRead: function onRead(app, device) { this.worker.remote.runExtension('onRead', device.id); }, beforeFirmwareUpdate: function beforeFirmwareUpdate(app, device) { this.worker.remote.runExtension('beforeFirmwareUpdate', device.id); }, afterFirmwareUpdate: function afterFirmwareUpdate(app, device) { this.worker.remote.runExtension('afterFirmwareUpdate', device.id); } }; class ExtVdrGroveLora { constructor() { this.checkFirmwareInForce = typeof checkFirmwareInForce !== 'undefined' ? checkFirmwareInForce : false; const handlerProxyUrl = window.MbApi.getExtResPath('vdr_grove_lora/handlerProxy.js', 'vdr_grove_lora'); const that = this; that.workerSetup = async function (exports) { that.worker = await window.__web_worker_rpc.create(handlerProxyUrl, exports).then(worker => { worker.CONFIG.TIMEOUT = 42000; worker.CONFIG.HEARTBEAT = 4200; worker.onFail = () => { that.worker = null; that.workerSetup(exports); const app = exports.app; if (app) { app.workspace.resetEvents(); } }; return worker; }); }; this.funcs = { 'BLOCK_1653809874148': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653809874148', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653809874506': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653809874506', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653809874838': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653809874838', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653809875114': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653809875114', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653809875483': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653809875483', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653809875786': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653809875786', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653809876062': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653809876062', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653809876310': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653809876310', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653809876594': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653809876594', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } } }; } getInfo() { return { "id": "vdr_grove_lora", "targets": [{ "name": "arduino_mega2560", "options": { "upload": { "middlewares": [{ "name": "arduino", "params": { "sources": extSources.arduino } }] } } }, { "name": "arduino_uno", "options": { "upload": { "middlewares": [{ "name": "arduino", "params": { "sources": extSources.arduino } }] } } }], "codeTypes": ["arduinoc"], "version": "1.0.0", "platform": ["mblockpc"], "categories": [{ "name": "cate_25f02c8a", "colors": ["#42CCFF", "#22C3FF", "#02BBFF"], "menuIconURI": "", "blockIcon": { "type": "image", "width": 28, "height": 26, "src": window.MbApi.getExtResPath('vdr_grove_lora/imgs/48687157c9ad4d6fa1243bebe8e94267.png', 'vdr_grove_lora') }, "blocks": [{ "opcode": "BLOCK_1653809874148", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "frequence": { "type": "fieldMenu", "defaultValue": "433.0", "menu": "BLOCK_1653809874148_FREQUENCE" }, "pinDigit": { "type": "fieldMenu", "defaultValue": "2", "menu": "BLOCK_1653809874148_PINDIGIT" }, "nbData": { "type": "fieldMenu", "defaultValue": "5", "menu": "BLOCK_1653809874148_NBDATA" } }, "branchCount": 0, "codes": { "arduinoc": { "sections": { "include": ["\"src/RH_RF95.h\""], "declare": `SoftwareSerial LoraSerial(/*{pinDigit}*/, /*{pinDigit}*/ + 1);\r\nRH_RF95 rf95(LoraSerial);\r\n\r\nString rf95sData;\r\nconst int rf95nbData = /*{nbData}*/; \r\nfloat rf95fDatas[rf95nbData];\r\n\r\nvoid rf95resetFDatas(){\r\n for ( int i = 0 ; i < rf95nbData ; i++ ) {\r\n rf95fDatas[i]=0;\r\n }\r\n}\r`, "setup": ` while (!rf95.init()) {\r\n }\r\n rf95.setFrequency(/*{frequence}*/);` } } }, "handler": this.funcs.BLOCK_1653809874148 }, { "opcode": "BLOCK_1653809874506", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "index": { "type": "number", "defaultValue": 1 }, "data": { "type": "number", "defaultValue": 10 } }, "branchCount": 0, "codes": { "arduinoc": { "code": `rf95setFDatas(/*{index}*/,/*{data}*/);`, "sections": { "declare": `void rf95setFDatas(int i, float data){\r\n if ((i>=0) && (i=0) && (i5>5handlerProxy.js"use strict";function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg),value=info.value}catch(error){return void reject(error)}info.done?resolve(value):Promise.resolve(value).then(_next,_throw)}function _asyncToGenerator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}var gen=fn.apply(self,args);_next(void 0)})}}function _instanceof(left,right){return null!=right&&"undefined"!=typeof Symbol&&right[Symbol.hasInstance]?!!right[Symbol.hasInstance](left):left instanceof right}function _typeof(obj){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(obj){return typeof obj}:function(obj){return obj&&"function"==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj},_typeof(obj)}self.rpc.CONFIG.TIMEOUT=42e3,self.rpc.CONFIG.HEARTBEAT=4200;var __context={app:self.rpc.remote.app,getDevice:function(deviceId){return new Proxy({},{get:function get(target,name){return"id"==name?deviceId:function(){for(var runDevice=__context.app.runDevice,_len=arguments.length,args=Array(_len),_key=0;_key<_len;_key++)args[_key]=arguments[_key];return runDevice.apply(void 0,[deviceId,name].concat(args))}}})}};!function(global){"use strict";function wrap(innerFn,outerFn,self,tryLocsList){var protoGenerator=outerFn&&_instanceof(outerFn.prototype,Generator)?outerFn:Generator,generator=Object.create(protoGenerator.prototype),context=new Context(tryLocsList||[]);return generator._invoke=makeInvokeMethod(innerFn,self,context),generator}function tryCatch(fn,obj,arg){try{return{type:"normal",arg:fn.call(obj,arg)}}catch(err){return{type:"throw",arg:err}}}function Generator(){}function GeneratorFunction(){}function GeneratorFunctionPrototype(){}function defineIteratorMethods(prototype){["next","throw","return"].forEach(function(method){prototype[method]=function(arg){return this._invoke(method,arg)}})}function AsyncIterator(generator){function invoke(method,arg,resolve,reject){var record=tryCatch(generator[method],generator,arg);if("throw"===record.type)reject(record.arg);else{var result=record.arg,value=result.value;return value&&"object"===_typeof(value)&&hasOwn.call(value,"__await")?Promise.resolve(value.__await).then(function(value){invoke("next",value,resolve,reject)},function(err){invoke("throw",err,resolve,reject)}):Promise.resolve(value).then(function(unwrapped){result.value=unwrapped,resolve(result)},function(error){return invoke("throw",error,resolve,reject)})}}function enqueue(method,arg){function callInvokeWithMethodAndArg(){return new Promise(function(resolve,reject){invoke(method,arg,resolve,reject)})}return previousPromise=previousPromise?previousPromise.then(callInvokeWithMethodAndArg,callInvokeWithMethodAndArg):callInvokeWithMethodAndArg()}var previousPromise;this._invoke=enqueue}function makeInvokeMethod(innerFn,self,context){var state="suspendedStart";return function(method,arg){if(state==="executing")throw new Error("Generator is already running");if("completed"===state){if("throw"===method)throw arg;return doneResult()}for(context.method=method,context.arg=arg;;){var delegate=context.delegate;if(delegate){var delegateResult=maybeInvokeDelegate(delegate,context);if(delegateResult){if(delegateResult===ContinueSentinel)continue;return delegateResult}}if("next"===context.method)context.sent=context._sent=context.arg;else if("throw"===context.method){if("suspendedStart"===state)throw state="completed",context.arg;context.dispatchException(context.arg)}else"return"===context.method&&context.abrupt("return",context.arg);state="executing";var record=tryCatch(innerFn,self,context);if("normal"===record.type){if(state=context.done?"completed":"suspendedYield",record.arg===ContinueSentinel)continue;return{value:record.arg,done:context.done}}"throw"===record.type&&(state="completed",context.method="throw",context.arg=record.arg)}}}function maybeInvokeDelegate(delegate,context){var method=delegate.iterator[context.method];if(void 0===method){if(context.delegate=null,"throw"===context.method){if(delegate.iterator.return&&(context.method="return",context.arg=void 0,maybeInvokeDelegate(delegate,context),"throw"===context.method))return ContinueSentinel;context.method="throw",context.arg=new TypeError("The iterator does not provide a 'throw' method")}return ContinueSentinel}var record=tryCatch(method,delegate.iterator,context.arg);if("throw"===record.type)return context.method="throw",context.arg=record.arg,context.delegate=null,ContinueSentinel;var info=record.arg;if(!info)return context.method="throw",context.arg=new TypeError("iterator result is not an object"),context.delegate=null,ContinueSentinel;if(info.done)context[delegate.resultName]=info.value,context.next=delegate.nextLoc,"return"!==context.method&&(context.method="next",context.arg=void 0);else return info;return context.delegate=null,ContinueSentinel}function pushTryEntry(locs){var entry={tryLoc:locs[0]};1 in locs&&(entry.catchLoc=locs[1]),2 in locs&&(entry.finallyLoc=locs[2],entry.afterLoc=locs[3]),this.tryEntries.push(entry)}function resetTryEntry(entry){var record=entry.completion||{};record.type="normal",delete record.arg,entry.completion=record}function Context(tryLocsList){this.tryEntries=[{tryLoc:"root"}],tryLocsList.forEach(pushTryEntry,this),this.reset(!0)}function values(iterable){if(iterable){var iteratorMethod=iterable[iteratorSymbol];if(iteratorMethod)return iteratorMethod.call(iterable);if("function"==typeof iterable.next)return iterable;if(!isNaN(iterable.length)){var i=-1,next=function next(){for(;++i= 0; --i) { var entry = this.tryEntries[i]; var record = entry.completion; if (entry.tryLoc === "root") { return handle("end") } if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"); var hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true) } else if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc) } } else if (hasCatch) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true) } } else if (hasFinally) { if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc) } } else { throw new Error("try statement without catch or finally") } } } }, abrupt: function(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break } } if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) { finallyEntry = null } var record = finallyEntry ? finallyEntry.completion : {}; record.type = type; record.arg = arg; if (finallyEntry) { this.method = "next"; this.next = finallyEntry.finallyLoc; return ContinueSentinel } return this.complete(record) }, complete: function(record, afterLoc) { if (record.type === "throw") { throw record.arg } if (record.type === "break" || record.type === "continue") { this.next = record.arg } else if (record.type === "return") { this.rval = this.arg = record.arg; this.method = "return"; this.next = "end" } else if (record.type === "normal" && afterLoc) { this.next = afterLoc } return ContinueSentinel }, finish: function(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) { this.complete(entry.completion, entry.afterLoc); resetTryEntry(entry); return ContinueSentinel } } }, "catch": function(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if (record.type === "throw") { var thrown = record.arg; resetTryEntry(entry) } return thrown } } throw new Error("illegal catch attempt") }, delegateYield: function(iterable, resultName, nextLoc) { this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }; if (this.method === "next") { this.arg = undefined } return ContinueSentinel } } }(function() { return this || typeof self === "object" && self }() || Function("return this")()); // enter your javascript code here const disableBlocks = { debug: [], upload: [] }; const mustLoginBlocks = []; const triggerBlocksStatus = async (mode, app) => {} class ExtVdrGroveLora { constructor() { this.funcs = { 'BLOCK_1653809874148': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653809874148', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653809874506': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653809874506', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653809874838': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653809874838', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653809875114': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653809875114', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653809875483': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653809875483', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653809875786': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653809875786', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653809876062': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653809876062', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653809876310': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653809876310', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653809876594': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653809876594', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } } }; } getInfo() { return { "id": "vdr_grove_lora", "targets": [{ "name": "arduino_mega2560", "options": { "upload": { "middlewares": [{ "name": "arduino", "params": { "sources": extSources.arduino } }] } } }, { "name": "arduino_uno", "options": { "upload": { "middlewares": [{ "name": "arduino", "params": { "sources": extSources.arduino } }] } } } ], "codeTypes": [ "arduinoc" ], "version": "1.0.0", "platform": [ "mblockpc" ], "categories": cates(facepanels), "generators": extGenerators, "translationMap": extTranslationMap, "snippets": codeSnippets, "generatorStartBlocks": [], "feature": [ "worker" ], "mustLoginBlocks": [], "disabledOffline": [], "disabledOnline": [] }; } getHandler() { if (typeof extHandler === 'object') { return extHandler; } else if (typeof extHandler === 'function') { return new extHandler(); } } } export default ExtVdrGroveLora;PK :~T"v&&src/snippets.jsexport default [ "arduinoc: {}" ];PK :~TI~src/generators.jsexport default [({ lang: 'arduinoc', template: `// generated by mBlock5 for // codes make you happy //( include //) #include //( lib //) //({ this.$ALL_VARIABLES.length==0?'':this.$ALL_VARIABLES.map(v=>"float "+v+" = 0;").join('\\n') }//) //( declare //) void _delay(float seconds) { long endTime = millis() + seconds * 1000; while(millis() < endTime) _loop(); } //( void setup() { //( setup //) //( code //) } //) void _loop() { //( _loop //) } void loop() { _loop(); }`, splitor: { frame: { left: "//(", right: "//)", }, expression: { left: "/*{", right: "}*/", } }, reducers: [{ name: 'include', reduce: (codes) => { let codes1 = [] for (let code of codes) { let codeStr = ''; if (typeof code === 'string') { codeStr = code; } else if (typeof code === 'function') { codeStr = code(); } if (codes1.indexOf(codeStr) === -1) { codes1.push(codeStr); } } if (codes1.length === 0) { return undefined; } return codes1.map(code => { return '#include ' + code; }).join('\n') + '\n' } }] })];PK :~T'l77src/arduinosources.jsexport default [ "{ filename: \"src/atomic.h\", code: \"/*\\n This is port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3\\n v1.0\\n Mark Pendrith, Nov 27, 2012.\\n\\n From Mark:\\n >When I ported the macros I emailed Dean to ask what attribution would be\\n >appropriate, and here is his response:\\n >\\n >>Mark,\\n >>I think it's great that you've ported the macros; consider them\\n >>public domain, to do with whatever you wish. I hope you find them >useful .\\n >>\\n >>Cheers!\\n >>- Dean\\n*/\\n\\n#ifdef __arm__\\n#ifndef _CORTEX_M3_ATOMIC_H_\\n#define _CORTEX_M3_ATOMIC_H_\\n\\nstatic __inline__ uint32_t __get_primask(void) \\\\\\n{\\n uint32_t primask = 0; \\\\\\n __asm__ volatile(\\\"MRS %[result], PRIMASK\\\\n\\\\t\\\":[result]\\\"=r\\\"(primask)::); \\\\\\n return primask;\\n} // returns 0 if interrupts enabled, 1 if disabled\\n\\nstatic __inline__ void __set_primask(uint32_t setval) \\\\\\n{\\n __asm__ volatile(\\\"MSR PRIMASK, %[value]\\\\n\\\\t\\\"\\\"dmb\\\\n\\\\t\\\"\\\"dsb\\\\n\\\\t\\\"\\\"isb\\\\n\\\\t\\\"::[value]\\\"r\\\"(setval):);\\n __asm__ volatile(\\\"\\\" ::: \\\"memory\\\");\\n}\\n\\nstatic __inline__ uint32_t __iSeiRetVal(void) \\\\\\n{\\n __asm__ volatile(\\\"CPSIE i\\\\n\\\\t\\\"\\\"dmb\\\\n\\\\t\\\"\\\"dsb\\\\n\\\\t\\\"\\\"isb\\\\n\\\\t\\\"); \\\\\\n __asm__ volatile(\\\"\\\" ::: \\\"memory\\\"); return 1;\\n}\\n\\nstatic __inline__ uint32_t __iCliRetVal(void) \\\\\\n{\\n __asm__ volatile(\\\"CPSID i\\\\n\\\\t\\\"\\\"dmb\\\\n\\\\t\\\"\\\"dsb\\\\n\\\\t\\\"\\\"isb\\\\n\\\\t\\\"); \\\\\\n __asm__ volatile(\\\"\\\" ::: \\\"memory\\\"); return 1;\\n}\\n\\nstatic __inline__ void __iSeiParam(const uint32_t* __s) \\\\\\n{\\n __asm__ volatile(\\\"CPSIE i\\\\n\\\\t\\\"\\\"dmb\\\\n\\\\t\\\"\\\"dsb\\\\n\\\\t\\\"\\\"isb\\\\n\\\\t\\\"); \\\\\\n __asm__ volatile(\\\"\\\" ::: \\\"memory\\\"); (void)__s;\\n}\\n\\nstatic __inline__ void __iCliParam(const uint32_t* __s) \\\\\\n{\\n __asm__ volatile(\\\"CPSID i\\\\n\\\\t\\\"\\\"dmb\\\\n\\\\t\\\"\\\"dsb\\\\n\\\\t\\\"\\\"isb\\\\n\\\\t\\\"); \\\\\\n __asm__ volatile(\\\"\\\" ::: \\\"memory\\\"); (void)__s;\\n}\\n\\nstatic __inline__ void __iRestore(const uint32_t* __s) \\\\\\n{\\n __set_primask(*__s); __asm__ volatile(\\\"dmb\\\\n\\\\t\\\"\\\"dsb\\\\n\\\\t\\\"\\\"isb\\\\n\\\\t\\\"); \\\\\\n __asm__ volatile(\\\"\\\" ::: \\\"memory\\\");\\n}\\n\\n\\n#define ATOMIC_BLOCK(type) \\\\\\n for ( type, __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0 )\\n\\n#define ATOMIC_RESTORESTATE \\\\\\n uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask()\\n\\n#define ATOMIC_FORCEON \\\\\\n uint32_t primask_save __attribute__((__cleanup__(__iSeiParam))) = 0\\n\\n#define NONATOMIC_BLOCK(type) \\\\\\n for ( type, __ToDo = __iSeiRetVal(); __ToDo ; __ToDo = 0 )\\n\\n#define NONATOMIC_RESTORESTATE \\\\\\n uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask()\\n\\n#define NONATOMIC_FORCEOFF \\\\\\n uint32_t primask_save __attribute__((__cleanup__(__iCliParam))) = 0\\n\\n#endif\\n#endif\\n\" }", "{ filename: \"src/RadioHead.h\", code: \"#ifndef RadioHead_h\\n#define RadioHead_h\\n\\n// Official version numbers are maintained automatically by Makefile:\\n#define RH_VERSION_MAJOR 1\\n#define RH_VERSION_MINOR 57\\n\\n// Symbolic names for currently supported platform types\\n#define RH_PLATFORM_ARDUINO 1\\n#define RH_PLATFORM_MSP430 2\\n#define RH_PLATFORM_STM32 3\\n#define RH_PLATFORM_GENERIC_AVR8 4\\n#define RH_PLATFORM_UNO32 5\\n#define RH_PLATFORM_UNIX 6\\n#define RH_PLATFORM_STM32STD 7\\n#define RH_PLATFORM_STM32F4_HAL 8\\n#define RH_PLATFORM_RASPI 9\\n#define RH_PLATFORM_NRF51 10\\n#define RH_PLATFORM_ESP8266 11\\n#define RH_PLATFORM_STM32F2 12\\n\\n////////////////////////////////////////////////////\\n// Select platform automatically, if possible\\n#ifndef RH_PLATFORM\\n #if defined(MPIDE)\\n #define RH_PLATFORM RH_PLATFORM_UNO32\\n #elif defined(NRF51)\\n #define RH_PLATFORM RH_PLATFORM_NRF51\\n #elif defined(ESP8266)\\n #define RH_PLATFORM RH_PLATFORM_ESP8266\\n #elif defined(ARDUINO)\\n #define RH_PLATFORM RH_PLATFORM_ARDUINO\\n #elif defined(__MSP430G2452__) || defined(__MSP430G2553__)\\n #define RH_PLATFORM RH_PLATFORM_MSP430\\n #elif defined(MCU_STM32F103RE)\\n #define RH_PLATFORM RH_PLATFORM_STM32\\n #elif defined(STM32F2XX)\\n #define RH_PLATFORM RH_PLATFORM_STM32F2\\n #elif defined(USE_STDPERIPH_DRIVER)\\n #define RH_PLATFORM RH_PLATFORM_STM32STD\\n #elif defined(RASPBERRY_PI)\\n #define RH_PLATFORM RH_PLATFORM_RASPI\\n #elif defined(__unix__) // Linux\\n #define RH_PLATFORM RH_PLATFORM_UNIX\\n #elif defined(__APPLE__) // OSX\\n #define RH_PLATFORM RH_PLATFORM_UNIX\\n #else\\n #error Platform not defined!\\n #endif\\n#endif\\n\\n#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtinyX4__) || defined(__AVR_ATtinyX5__) || defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny4313__) || defined(__AVR_ATtinyX313__)\\n #define RH_PLATFORM_ATTINY\\n#endif\\n\\n////////////////////////////////////////////////////\\n// Platform specific headers:\\n#if (RH_PLATFORM == RH_PLATFORM_ARDUINO)\\n #if (ARDUINO >= 100)\\n #include \\n #endif\\n#endif\\n\\n////////////////////////////////////////////////////\\n// This is an attempt to make a portable atomic block\\n#if (RH_PLATFORM == RH_PLATFORM_ARDUINO)\\n #if defined(__arm__)\\n #include \\n #endif\\n #define ATOMIC_BLOCK_START ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {\\n #define ATOMIC_BLOCK_END }\\n#endif\\n\\n////////////////////////////////////////////////////\\n// Try to be compatible with systems that support yield() and multitasking\\n// instead of spin-loops\\n// Recent Arduino IDE or Teensy 3 has yield()\\n#if (RH_PLATFORM == RH_PLATFORM_ARDUINO && ARDUINO >= 155 && !defined(RH_PLATFORM_ATTINY)) || (TEENSYDUINO && defined(__MK20DX128__))\\n #define YIELD yield();\\n#endif\\n\\n////////////////////////////////////////////////////\\n// digitalPinToInterrupt is not available prior to Arduino 1.5.6 and 1.0.6\\n// See http://arduino.cc/en/Reference/attachInterrupt\\n#ifndef NOT_AN_INTERRUPT\\n #define NOT_AN_INTERRUPT -1\\n#endif\\n#ifndef digitalPinToInterrupt\\n\\n // All other arduino except Due:\\n // Serial Arduino, Extreme, NG, BT, Uno, Diecimila, Duemilanove, Nano, Menta, Pro, Mini 04, Fio, LilyPad, Ethernet etc\\n // 2->0, 3->1\\n #define digitalPinToInterrupt(p) ((p) == 2 ? 0 : ((p) == 3 ? 1 : NOT_AN_INTERRUPT))\\n\\n#endif\\n\\n// On some platforms, attachInterrupt() takes a pin number, not an interrupt number\\n#if (RH_PLATFORM == RH_PLATFORM_ARDUINO) && defined (__arm__) && (defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_SAM_DUE))\\n #define RH_ATTACHINTERRUPT_TAKES_PIN_NUMBER\\n#endif\\n\\n// Slave select pin, some platforms such as ATTiny do not define it.\\n#ifndef SS\\n #define SS 10\\n#endif\\n\\n// These defs cause trouble on some versions of Arduino\\n#undef abs\\n#undef round\\n#undef double\\n\\n// Sigh: there is no widespread adoption of htons and friends in the base code, only in some WiFi headers etc\\n// that have a lot of excess baggage\\n#if RH_PLATFORM != RH_PLATFORM_UNIX && !defined(htons)\\n// #ifndef htons\\n// These predefined macros availble on modern GCC compilers\\n#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\\n// Atmel processors\\n#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) )\\n#define ntohs(x) htons(x)\\n#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \\\\\\n ((x)<< 8 & 0x00FF0000UL) | \\\\\\n ((x)>> 8 & 0x0000FF00UL) | \\\\\\n ((x)>>24 & 0x000000FFUL) )\\n#define ntohl(x) htonl(x)\\n\\n#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__\\n// Others\\n#define htons(x) (x)\\n#define ntohs(x) (x)\\n#define htonl(x) (x)\\n#define ntohl(x) (x)\\n\\n#else\\n#error \\\"Dont know how to define htons and friends for this processor\\\"\\n#endif\\n#endif\\n\\n// This is the address that indicates a broadcast\\n#define RH_BROADCAST_ADDRESS 0xff\\n\\n#endif\\n\" }", "{ filename: \"src/RHGenericDriver.cpp\", code: \"// RHGenericDriver.cpp\\n//\\n// Copyright (C) 2014 Mike McCauley\\n// $Id: RHGenericDriver.cpp,v 1.19 2015/12/11 01:10:24 mikem Exp $\\n\\n#include \\\"RHGenericDriver.h\\\"\\n\\nRHGenericDriver::RHGenericDriver()\\n :\\n _mode(RHModeInitialising),\\n _thisAddress(RH_BROADCAST_ADDRESS),\\n _txHeaderTo(RH_BROADCAST_ADDRESS),\\n _txHeaderFrom(RH_BROADCAST_ADDRESS),\\n _txHeaderId(0),\\n _txHeaderFlags(0),\\n _rxBad(0),\\n _rxGood(0),\\n _txGood(0) {\\n}\\n\\nbool RHGenericDriver::init() {\\n return true;\\n}\\n\\n// Blocks until a valid message is received\\nvoid RHGenericDriver::waitAvailable() {\\n while (!available()) {\\n YIELD;\\n }\\n}\\n\\n// Blocks until a valid message is received or timeout expires\\n// Return true if there is a message available\\n// Works correctly even on millis() rollover\\nbool RHGenericDriver::waitAvailableTimeout(uint16_t timeout) {\\n unsigned long starttime = millis();\\n while ((millis() - starttime) < timeout) {\\n if (available()) {\\n return true;\\n }\\n YIELD;\\n }\\n return false;\\n}\\n\\nbool RHGenericDriver::waitPacketSent() {\\n while (_mode == RHModeTx) {\\n available();\\n YIELD; // Wait for any previous transmit to finish\\n }\\n\\n return true;\\n}\\n\\nbool RHGenericDriver::waitPacketSent(uint16_t timeout) {\\n unsigned long starttime = millis();\\n while ((millis() - starttime) < timeout) {\\n if (_mode != RHModeTx) { // Any previous transmit finished?\\n return true;\\n }\\n available();\\n YIELD;\\n }\\n return false;\\n}\\n\\nvoid RHGenericDriver::setPromiscuous(bool promiscuous) {\\n _promiscuous = promiscuous;\\n}\\n\\nvoid RHGenericDriver::setThisAddress(uint8_t address) {\\n _thisAddress = address;\\n}\\n\\nvoid RHGenericDriver::setHeaderTo(uint8_t to) {\\n _txHeaderTo = to;\\n}\\n\\nvoid RHGenericDriver::setHeaderFrom(uint8_t from) {\\n _txHeaderFrom = from;\\n}\\n\\nvoid RHGenericDriver::setHeaderId(uint8_t id) {\\n _txHeaderId = id;\\n}\\n\\nvoid RHGenericDriver::setHeaderFlags(uint8_t set, uint8_t clear) {\\n _txHeaderFlags &= ~clear;\\n _txHeaderFlags |= set;\\n}\\n\\nuint8_t RHGenericDriver::headerTo() {\\n return _rxHeaderTo;\\n}\\n\\nuint8_t RHGenericDriver::headerFrom() {\\n return _rxHeaderFrom;\\n}\\n\\nuint8_t RHGenericDriver::headerId() {\\n return _rxHeaderId;\\n}\\n\\nuint8_t RHGenericDriver::headerFlags() {\\n return _rxHeaderFlags;\\n}\\n\\nint8_t RHGenericDriver::lastRssi() {\\n return _lastRssi;\\n}\\n\\nRHGenericDriver::RHMode RHGenericDriver::mode() {\\n return _mode;\\n}\\n\\nvoid RHGenericDriver::setMode(RHMode mode) {\\n _mode = mode;\\n}\\n\\nbool RHGenericDriver::sleep() {\\n return false;\\n}\\n\\n// Diagnostic help\\nvoid RHGenericDriver::printBuffer(const char* prompt, const uint8_t* buf, uint8_t len) {\\n uint8_t i;\\n\\n #ifdef RH_HAVE_SERIAL\\n Serial.println(prompt);\\n for (i = 0; i < len; i++) {\\n if (i % 16 == 15) {\\n Serial.println(buf[i], HEX);\\n } else {\\n Serial.print(buf[i], HEX);\\n Serial.print(' ');\\n }\\n }\\n Serial.println(\\\"\\\");\\n #endif\\n}\\n\\nuint16_t RHGenericDriver::rxBad() {\\n return _rxBad;\\n}\\n\\nuint16_t RHGenericDriver::rxGood() {\\n return _rxGood;\\n}\\n\\nuint16_t RHGenericDriver::txGood() {\\n return _txGood;\\n}\\n\\n#if (RH_PLATFORM == RH_PLATFORM_ARDUINO) && defined(RH_PLATFORM_ATTINY)\\n// Tinycore does not have __cxa_pure_virtual, so without this we\\n// get linking complaints from the default code generated for pure virtual functions\\nextern \\\"C\\\" void __cxa_pure_virtual() {\\n while (1);\\n}\\n#endif\\n\" }", "{ filename: \"src/RHGenericDriver.h\", code: \"// RHGenericDriver.h\\n// Author: Mike McCauley (mikem@airspayce.com)\\n// Copyright (C) 2014 Mike McCauley\\n// $Id: RHGenericDriver.h,v 1.16 2015/01/02 21:38:24 mikem Exp $\\n\\n#ifndef RHGenericDriver_h\\n#define RHGenericDriver_h\\n\\n#include \\\"RadioHead.h\\\"\\n\\n// Defines bits of the FLAGS header reserved for use by the RadioHead library and\\n// the flags available for use by applications\\n#define RH_FLAGS_RESERVED 0xf0\\n#define RH_FLAGS_APPLICATION_SPECIFIC 0x0f\\n#define RH_FLAGS_NONE 0\\n\\n/////////////////////////////////////////////////////////////////////\\n/// \\\\class RHGenericDriver RHGenericDriver.h \\n/// \\\\brief Abstract base class for a RadioHead driver.\\n///\\n/// This class defines the functions that must be provided by any RadioHead driver.\\n/// Different types of driver will implement all the abstract functions, and will perhaps override\\n/// other functions in this subclass, or perhaps add new functions specifically required by that driver.\\n/// Do not directly instantiate this class: it is only to be subclassed by driver classes.\\n///\\n/// Subclasses are expected to implement a half-duplex, unreliable, error checked, unaddressed packet transport.\\n/// They are expected to carry a message payload with an appropriate maximum length for the transport hardware\\n/// and to also carry unaltered 4 message headers: TO, FROM, ID, FLAGS\\n///\\n/// \\\\par Headers\\n///\\n/// Each message sent and received by a RadioHead driver includes 4 headers:\\n/// -TO The node address that the message is being sent to (broadcast RH_BROADCAST_ADDRESS (255) is permitted)\\n/// -FROM The node address of the sending node\\n/// -ID A message ID, distinct (over short time scales) for each message sent by a particilar node\\n/// -FLAGS A bitmask of flags. The most significant 4 bits are reserved for use by RadioHead. The least\\n/// significant 4 bits are reserved for applications.\\nclass RHGenericDriver {\\n public:\\n /// \\\\brief Defines different operating modes for the transport hardware\\n ///\\n /// These are the different values that can be adopted by the _mode variable and\\n /// returned by the mode() member function,\\n typedef enum {\\n RHModeInitialising = 0, ///< Transport is initialising. Initial default value until init() is called..\\n RHModeSleep, ///< Transport hardware is in low power sleep mode (if supported)\\n RHModeIdle, ///< Transport is idle.\\n RHModeTx, ///< Transport is in the process of transmitting a message.\\n RHModeRx ///< Transport is in the process of receiving a message.\\n } RHMode;\\n\\n /// Constructor\\n RHGenericDriver();\\n\\n /// Initialise the Driver transport hardware and software.\\n /// Make sure the Driver is properly configured before calling init().\\n /// \\\\return true if initialisation succeeded.\\n virtual bool init();\\n\\n /// Tests whether a new message is available\\n /// from the Driver.\\n /// On most drivers, if there is an uncollected received message, and there is no message\\n /// currently bing transmitted, this will also put the Driver into RHModeRx mode until\\n /// a message is actually received by the transport, when it will be returned to RHModeIdle.\\n /// This can be called multiple times in a timeout loop.\\n /// \\\\return true if a new, complete, error-free uncollected message is available to be retreived by recv().\\n virtual bool available() = 0;\\n //virtual bool available(){};\\n\\n /// Turns the receiver on if it not already on.\\n /// If there is a valid message available, copy it to buf and return true\\n /// else return false.\\n /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).\\n /// You should be sure to call this function frequently enough to not miss any messages\\n /// It is recommended that you call it in your main loop.\\n /// \\\\param[in] buf Location to copy the received message\\n /// \\\\param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.\\n /// \\\\return true if a valid message was copied to buf\\n virtual bool recv(uint8_t* buf, uint8_t* len) = 0;\\n //virtual bool recv(uint8_t* buf, uint8_t* len){};\\n\\n /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().\\n /// Then loads a message into the transmitter and starts the transmitter. Note that a message length\\n /// of 0 is NOT permitted. If the message is too long for the underlying radio technology, send() will\\n /// return false and will not send the message.\\n /// \\\\param[in] data Array of data to be sent\\n /// \\\\param[in] len Number of bytes of data to send (> 0)\\n /// \\\\return true if the message length was valid and it was correctly queued for transmit\\n virtual bool send(uint8_t* data, uint8_t len) = 0;\\n //virtual bool send(uint8_t* data, uint8_t len){};\\n\\n /// Returns the maximum message length\\n /// available in this Driver.\\n /// \\\\return The maximum legal message length\\n virtual uint8_t maxMessageLength() = 0;\\n //virtual uint8_t maxMessageLength(){};\\n\\n /// Starts the receiver and blocks until a valid received\\n /// message is available.\\n virtual void waitAvailable();\\n\\n /// Blocks until the transmitter\\n /// is no longer transmitting.\\n virtual bool waitPacketSent();\\n\\n /// Blocks until the transmitter is no longer transmitting.\\n /// or until the timeout occuers, whichever happens first\\n /// \\\\param[in] timeout Maximum time to wait in milliseconds.\\n /// \\\\return true if the RF22 completed transmission within the timeout period. False if it timed out.\\n virtual bool waitPacketSent(uint16_t timeout);\\n\\n /// Starts the receiver and blocks until a received message is available or a timeout\\n /// \\\\param[in] timeout Maximum time to wait in milliseconds.\\n /// \\\\return true if a message is available\\n virtual bool waitAvailableTimeout(uint16_t timeout);\\n\\n /// Sets the address of this node. Defaults to 0xFF. Subclasses or the user may want to change this.\\n /// This will be used to test the adddress in incoming messages. In non-promiscuous mode,\\n /// only messages with a TO header the same as thisAddress or the broadcast addess (0xFF) will be accepted.\\n /// In promiscuous mode, all messages will be accepted regardless of the TO header.\\n /// In a conventional multinode system, all nodes will have a unique address\\n /// (which you could store in EEPROM).\\n /// You would normally set the header FROM address to be the same as thisAddress (though you dont have to,\\n /// allowing the possibilty of address spoofing).\\n /// \\\\param[in] thisAddress The address of this node.\\n virtual void setThisAddress(uint8_t thisAddress);\\n\\n /// Sets the TO header to be sent in all subsequent messages\\n /// \\\\param[in] to The new TO header value\\n virtual void setHeaderTo(uint8_t to);\\n\\n /// Sets the FROM header to be sent in all subsequent messages\\n /// \\\\param[in] from The new FROM header value\\n virtual void setHeaderFrom(uint8_t from);\\n\\n /// Sets the ID header to be sent in all subsequent messages\\n /// \\\\param[in] id The new ID header value\\n virtual void setHeaderId(uint8_t id);\\n\\n /// Sets and clears bits in the FLAGS header to be sent in all subsequent messages\\n /// First it clears he FLAGS according to the clear argument, then sets the flags according to the\\n /// set argument. The default for clear always clears the application specific flags.\\n /// \\\\param[in] set bitmask of bits to be set. Flags are cleared with the clear mask before being set.\\n /// \\\\param[in] clear bitmask of flags to clear. Defaults to RH_FLAGS_APPLICATION_SPECIFIC\\n /// which clears the application specific flags, resulting in new application specific flags\\n /// identical to the set.\\n virtual void setHeaderFlags(uint8_t set, uint8_t clear = RH_FLAGS_APPLICATION_SPECIFIC);\\n\\n /// Tells the receiver to accept messages with any TO address, not just messages\\n /// addressed to thisAddress or the broadcast address\\n /// \\\\param[in] promiscuous true if you wish to receive messages with any TO address\\n virtual void setPromiscuous(bool promiscuous);\\n\\n /// Returns the TO header of the last received message\\n /// \\\\return The TO header\\n virtual uint8_t headerTo();\\n\\n /// Returns the FROM header of the last received message\\n /// \\\\return The FROM header\\n virtual uint8_t headerFrom();\\n\\n /// Returns the ID header of the last received message\\n /// \\\\return The ID header\\n virtual uint8_t headerId();\\n\\n /// Returns the FLAGS header of the last received message\\n /// \\\\return The FLAGS header\\n virtual uint8_t headerFlags();\\n\\n /// Returns the most recent RSSI (Receiver Signal Strength Indicator).\\n /// Usually it is the RSSI of the last received message, which is measured when the preamble is received.\\n /// If you called readRssi() more recently, it will return that more recent value.\\n /// \\\\return The most recent RSSI measurement in dBm.\\n int8_t lastRssi();\\n\\n /// Returns the operating mode of the library.\\n /// \\\\return the current mode, one of RF69_MODE_*\\n RHMode mode();\\n\\n /// Sets the operating mode of the transport.\\n void setMode(RHMode mode);\\n\\n /// Sets the transport hardware into low-power sleep mode\\n /// (if supported). May be overridden by specific drivers to initialte sleep mode.\\n /// If successful, the transport will stay in sleep mode until woken by\\n /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc)\\n /// \\\\return true if sleep mode is supported by transport hardware and the RadioHead driver, and if sleep mode\\n /// was successfully entered. If sleep mode is not suported, return false.\\n virtual bool sleep();\\n\\n /// Prints a data buffer in HEX.\\n /// For diagnostic use\\n /// \\\\param[in] prompt string to preface the print\\n /// \\\\param[in] buf Location of the buffer to print\\n /// \\\\param[in] len Length of the buffer in octets.\\n static void printBuffer(const char* prompt, const uint8_t* buf, uint8_t len);\\n\\n /// Returns the count of the number of bad received packets (ie packets with bad lengths, checksum etc)\\n /// which were rejected and not delivered to the application.\\n /// Caution: not all drivers can correctly report this count. Some underlying hardware only report\\n /// good packets.\\n /// \\\\return The number of bad packets received.\\n uint16_t rxBad();\\n\\n /// Returns the count of the number of\\n /// good received packets\\n /// \\\\return The number of good packets received.\\n uint16_t rxGood();\\n\\n /// Returns the count of the number of\\n /// packets successfully transmitted (though not necessarily received by the destination)\\n /// \\\\return The number of packets successfully transmitted\\n uint16_t txGood();\\n\\n protected:\\n\\n /// The current transport operating mode\\n volatile RHMode _mode;\\n\\n /// This node id\\n uint8_t _thisAddress;\\n\\n /// Whether the transport is in promiscuous mode\\n bool _promiscuous;\\n\\n /// TO header in the last received mesasge\\n volatile uint8_t _rxHeaderTo;\\n\\n /// FROM header in the last received mesasge\\n volatile uint8_t _rxHeaderFrom;\\n\\n /// ID header in the last received mesasge\\n volatile uint8_t _rxHeaderId;\\n\\n /// FLAGS header in the last received mesasge\\n volatile uint8_t _rxHeaderFlags;\\n\\n /// TO header to send in all messages\\n uint8_t _txHeaderTo;\\n\\n /// FROM header to send in all messages\\n uint8_t _txHeaderFrom;\\n\\n /// ID header to send in all messages\\n uint8_t _txHeaderId;\\n\\n /// FLAGS header to send in all messages\\n uint8_t _txHeaderFlags;\\n\\n /// The value of the last received RSSI value, in some transport specific units\\n volatile int8_t _lastRssi;\\n\\n /// Count of the number of bad messages (eg bad checksum etc) received\\n volatile uint16_t _rxBad;\\n\\n /// Count of the number of successfully transmitted messaged\\n volatile uint16_t _rxGood;\\n\\n /// Count of the number of bad messages (correct checksum etc) received\\n volatile uint16_t _txGood;\\n\\n private:\\n\\n};\\n\\n\\n#endif\\n\" }", "{ filename: \"src/RHUartDriver.cpp\", code: \"#include \\\"RHUartDriver.h\\\"\\n\\ntemplate \\nRHUartDriver::RHUartDriver(T& ss)\\n :\\n _ss(ss) {\\n}\\n\\ntemplate \\nbool RHUartDriver::init() {\\n _ss.begin(57600);\\n // _ss.listen();\\n\\n return true;\\n}\\n\\ntemplate \\nuint8_t RHUartDriver::uartAvailable(void) {\\n return _ss.available();\\n}\\n\\ntemplate \\nuint8_t RHUartDriver::uartRead(void) {\\n return _ss.read();\\n}\\n\\ntemplate \\nvoid RHUartDriver::uartTx(uint8_t reg, uint8_t* src, uint8_t len) {\\n _ss.write('W');\\n _ss.write(reg);\\n _ss.write(len);\\n for (int i = 0; i < len; i ++) {\\n _ss.write(*(src + i));\\n }\\n}\\n\\ntemplate \\nvoid RHUartDriver::uartRx(uint8_t reg, uint8_t* dest, uint8_t len) {\\n _ss.write('R');\\n _ss.write(reg);\\n _ss.write(len);\\n\\n unsigned long timerStart, timerEnd;\\n int i = 0;\\n timerStart = millis();\\n while (1) {\\n if (_ss.available()) {\\n *(dest + i) = _ss.read();\\n i ++;\\n if (i >= len) {\\n break;\\n }\\n }\\n\\n timerEnd = millis();\\n if (timerEnd - timerStart > 1000 * DEFAULT_TIMEOUT) {\\n break;\\n }\\n }\\n}\\n\\ntemplate \\nuint8_t RHUartDriver::read(uint8_t reg) {\\n uint8_t val = 0;\\n uartRx(reg & ~RH_WRITE_MASK, &val, 1);\\n return val;\\n}\\n\\ntemplate \\nvoid RHUartDriver::write(uint8_t reg, uint8_t val) {\\n uartTx(reg | RH_WRITE_MASK, &val, 1);\\n}\\n\\ntemplate \\nvoid RHUartDriver::burstRead(uint8_t reg, uint8_t* dest, uint8_t len) {\\n uartRx(reg & ~RH_WRITE_MASK, dest, len);\\n}\\n\\ntemplate \\nvoid RHUartDriver::burstWrite(uint8_t reg, uint8_t* src, uint8_t len) {\\n uartTx(reg | RH_WRITE_MASK, src, len);\\n}\\n\\n\\n#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE\\n template class RHUartDriver;\\n#endif\\ntemplate class RHUartDriver;\\n\\n#ifdef __AVR__\\n #include \\n template class RHUartDriver;\\n#endif\" }", "{ filename: \"src/RHUartDriver.h\", code: \"/*\\n RHUartDriver.h\\n A library for Grove - Lora 433MHz/470MHz RF or Grove - Lora 868MHz/915MHz RF\\n\\n Copyright (c) 2015 seeed technology inc.\\n Website : www.seeed.cc\\n Author : JY.W\\n Modified Time: 2016-07-15\\n\\n The MIT License (MIT)\\n\\n Permission is hereby granted, free of charge, to any person obtaining a copy\\n of this software and associated documentation files (the \\\"Software\\\"), to deal\\n in the Software without restriction, including without limitation the rights\\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n copies of the Software, and to permit persons to whom the Software is\\n furnished to do so, subject to the following conditions:\\n\\n The above copyright notice and this permission notice shall be included in\\n all copies or substantial portions of the Software.\\n\\n THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\\n THE SOFTWARE.\\n*/\\n\\n#ifndef _RH_UART_Driver_H_\\n#define _RH_UART_Driver_H_\\n\\n\\n#include \\n#include \\\"RHGenericDriver.h\\\"\\n\\n\\n#define DEFAULT_TIMEOUT 3\\n\\n#define RH_WRITE_MASK 0x80\\n\\ntemplate\\nclass RHUartDriver : public RHGenericDriver {\\n public:\\n\\n RHUartDriver(T& ss);\\n\\n virtual bool init();\\n\\n uint8_t uartAvailable(void);\\n\\n uint8_t uartRead(void);\\n\\n // 'W' + 'Reg' + 'Len' + 'Data'\\n void uartTx(uint8_t reg, uint8_t* src, uint8_t len);\\n\\n // 'R' + 'Reg' + 'Len'\\n void uartRx(uint8_t reg, uint8_t* dest, uint8_t len);\\n\\n uint8_t read(uint8_t reg);\\n\\n void write(uint8_t reg, uint8_t val);\\n\\n void burstRead(uint8_t reg, uint8_t* dest, uint8_t len);\\n\\n void burstWrite(uint8_t reg, uint8_t* src, uint8_t len);\\n\\n protected:\\n\\n T& _ss;\\n\\n private:\\n\\n\\n\\n};\\n\\n#endif\\n\" }", "{ filename: \"src/RH_RF95.cpp\", code: \"\\n#include \\\"RH_RF95.h\\\"\\n\\n\\n// These are indexed by the values of ModemConfigChoice\\n// Stored in flash (program) memory to save SRAM\\nPROGMEM static const ModemConfig MODEM_CONFIG_TABLE[] = {\\n // 1d, 1e, 26\\n { 0x72, 0x74, 0x00}, // Bw125Cr45Sf128 (the chip default)\\n { 0x92, 0x74, 0x00}, // Bw500Cr45Sf128\\n { 0x48, 0x94, 0x00}, // Bw31_25Cr48Sf512\\n { 0x78, 0xc4, 0x00}, // Bw125Cr48Sf4096\\n\\n};\\n\\ntemplate \\nRH_RF95::RH_RF95(T& ss)\\n :\\n RHUartDriver(ss),\\n _rxBufValid(0) {\\n}\\n\\ntemplate \\nbool RH_RF95::init() {\\n RHUartDriver::init();\\n\\n // Set sleep mode, so we can also set LORA mode:\\n this->write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_SLEEP | RH_RF95_LONG_RANGE_MODE);\\n delay(10); // Wait for sleep mode to take over from say, CAD\\n\\n // Check we are in sleep mode, with LORA set\\n if (this->read(RH_RF95_REG_01_OP_MODE) != (RH_RF95_MODE_SLEEP | RH_RF95_LONG_RANGE_MODE)) {\\n Serial.println(this->read(RH_RF95_REG_01_OP_MODE), HEX);\\n return false; // No device present?\\n }\\n\\n // Set up FIFO\\n // We configure so that we can use the entire 256 byte FIFO for either receive\\n // or transmit, but not both at the same time\\n this->write(RH_RF95_REG_0E_FIFO_TX_BASE_ADDR, 0);\\n this->write(RH_RF95_REG_0F_FIFO_RX_BASE_ADDR, 0);\\n\\n // Packet format is preamble + explicit-header + payload + crc\\n // Explicit Header Mode\\n // payload is TO + FROM + ID + FLAGS + message data\\n // RX mode is implmented with RXCONTINUOUS\\n // max message data length is 255 - 4 = 251 octets\\n\\n setModeIdle();\\n\\n // Set up default configuration\\n // No Sync Words in LORA mode.\\n setModemConfig(Bw125Cr45Sf128); // Radio default\\n //setModemConfig(Bw125Cr48Sf4096); // slow and reliable?\\n setPreambleLength(8); // Default is 8\\n // An innocuous ISM frequency, same as RF22's\\n //setFrequency(434.0);\\n setFrequency(868.0);\\n // Lowish power\\n setTxPower(13);\\n\\n return true;\\n}\\n\\n// C++ level interrupt handler for this instance\\n// LORA is unusual in that it has several interrupt lines, and not a single, combined one.\\n// On MiniWirelessLoRa, only one of the several interrupt lines (DI0) from the RFM95 is usefuly\\n// connnected to the processor.\\n// We use this to get RxDone and TxDone interrupts\\n\\ntemplate \\nvoid RH_RF95::handleInterrupt() {\\n // Read the interrupt register\\n uint8_t irq_flags = this->read(RH_RF95_REG_12_IRQ_FLAGS);\\n if (this->_mode == RHGenericDriver::RHModeRx && irq_flags & (RH_RF95_RX_TIMEOUT | RH_RF95_PAYLOAD_CRC_ERROR)) {\\n this->_rxBad++;\\n } else if (this->_mode == RHGenericDriver::RHModeRx && irq_flags & RH_RF95_RX_DONE) {\\n // Have received a packet\\n uint8_t len = this->read(RH_RF95_REG_13_RX_NB_BYTES);\\n\\n // Reset the fifo this->read ptr to the beginning of the packet\\n this->write(RH_RF95_REG_0D_FIFO_ADDR_PTR, this->read(RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR));\\n this->burstRead(RH_RF95_REG_00_FIFO, _buf, len);\\n _bufLen = len;\\n this->write(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags\\n\\n // Remember the RSSI of this packet\\n // this is according to the doc, but is it really correct?\\n // weakest receiveable signals are reported RSSI at about -66\\n this->_lastRssi = this->read(RH_RF95_REG_1A_PKT_RSSI_VALUE) - 137;\\n\\n // We have received a message.\\n validateRxBuf();\\n if (_rxBufValid) {\\n setModeIdle(); // Got one\\n }\\n } else if (this->_mode == RHGenericDriver::RHModeTx && irq_flags & RH_RF95_TX_DONE) {\\n this->_txGood++;\\n setModeIdle();\\n }\\n\\n this->write(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags\\n}\\n\\n// Check whether the latest received message is complete and uncorrupted\\n\\ntemplate \\nvoid RH_RF95::validateRxBuf() {\\n if (_bufLen < 4) {\\n return; // Too short to be a real message\\n }\\n\\n // Extract the 4 headers\\n this->_rxHeaderTo = _buf[0];\\n this->_rxHeaderFrom = _buf[1];\\n this->_rxHeaderId = _buf[2];\\n this->_rxHeaderFlags = _buf[3];\\n\\n if (this->_promiscuous || this->_rxHeaderTo == this->_thisAddress || this->_rxHeaderTo == RH_BROADCAST_ADDRESS) {\\n this->_rxGood++;\\n _rxBufValid = true;\\n }\\n}\\n\\n\\ntemplate \\nbool RH_RF95::available() {\\n if (this->uartAvailable()) {\\n if (this->uartRead() == 'I') {\\n handleInterrupt();\\n }\\n }\\n\\n if (this->_mode == RHGenericDriver::RHModeTx) {\\n return false;\\n }\\n setModeRx();\\n\\n return _rxBufValid; // Will be set by the interrupt handler when a good message is received\\n}\\n\\ntemplate \\nvoid RH_RF95::clearRxBuf() {\\n _rxBufValid = false;\\n _bufLen = 0;\\n}\\n\\n\\ntemplate \\nbool RH_RF95::recv(uint8_t* buf, uint8_t* len) {\\n if (!available()) {\\n return false;\\n }\\n if (buf && len) {\\n // Skip the 4 headers that are at the beginning of the rxBuf\\n if (*len > _bufLen - RH_RF95_HEADER_LEN) {\\n *len = _bufLen - RH_RF95_HEADER_LEN;\\n }\\n memcpy(buf, _buf + RH_RF95_HEADER_LEN, *len);\\n }\\n clearRxBuf(); // This message accepted and cleared\\n return true;\\n}\\n\\n\\ntemplate \\nbool RH_RF95::send(uint8_t* data, uint8_t len) {\\n if (len > RH_RF95_MAX_MESSAGE_LEN) {\\n return false;\\n }\\n\\n this->waitPacketSent(); // Make sure we dont interrupt an outgoing message\\n setModeIdle();\\n\\n // Position at the beginning of the FIFO\\n this->write(RH_RF95_REG_0D_FIFO_ADDR_PTR, 0);\\n\\n // The headers\\n this->write(RH_RF95_REG_00_FIFO, this->_txHeaderTo);\\n this->write(RH_RF95_REG_00_FIFO, this->_txHeaderFrom);\\n this->write(RH_RF95_REG_00_FIFO, this->_txHeaderId);\\n this->write(RH_RF95_REG_00_FIFO, this->_txHeaderFlags);\\n\\n // The message data\\n this->burstWrite(RH_RF95_REG_00_FIFO, data, len);\\n this->write(RH_RF95_REG_22_PAYLOAD_LENGTH, len + RH_RF95_HEADER_LEN);\\n\\n setModeTx(); // Start the transmitter\\n // when Tx is done, interruptHandler will fire and radio mode will return to STANDBY\\n\\n //this->write(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags\\n return true;\\n}\\n\\n\\ntemplate \\nbool RH_RF95::printRegisters() {\\n #ifdef RH_HAVE_SERIAL\\n uint8_t registers[] = { 0x01, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x014, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27};\\n\\n uint8_t i;\\n for (i = 0; i < sizeof(registers); i++) {\\n Serial.print(registers[i], HEX);\\n Serial.print(\\\": \\\");\\n Serial.println(this->read(registers[i]), HEX);\\n }\\n #endif\\n return true;\\n}\\n\\n\\ntemplate \\nuint8_t RH_RF95::maxMessageLength() {\\n return RH_RF95_MAX_MESSAGE_LEN;\\n}\\n\\n\\ntemplate \\nbool RH_RF95::setFrequency(float centre) {\\n // Frf = FRF / FSTEP\\n uint32_t frf = (centre * 1000000.0) / RH_RF95_FSTEP;\\n this->write(RH_RF95_REG_06_FRF_MSB, (frf >> 16) & 0xff);\\n this->write(RH_RF95_REG_07_FRF_MID, (frf >> 8) & 0xff);\\n this->write(RH_RF95_REG_08_FRF_LSB, frf & 0xff);\\n\\n return true;\\n}\\n\\n\\ntemplate \\nvoid RH_RF95::setModeIdle() {\\n if (this->_mode != RHGenericDriver::RHModeIdle) {\\n this->write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_STDBY);\\n this->_mode = RHGenericDriver::RHModeIdle;\\n }\\n}\\n\\n\\ntemplate \\nbool RH_RF95::sleep() {\\n if (this->_mode != RHGenericDriver::RHModeSleep) {\\n this->write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_SLEEP);\\n this->_mode = RHGenericDriver::RHModeSleep;\\n }\\n return true;\\n}\\n\\n\\ntemplate \\nvoid RH_RF95::setModeRx() {\\n if (this->_mode != RHGenericDriver::RHModeRx) {\\n this->write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_RXCONTINUOUS);\\n this->write(RH_RF95_REG_40_DIO_MAPPING1, 0x00); // Interrupt on RxDone\\n this->_mode = RHGenericDriver::RHModeRx;\\n }\\n}\\n\\n\\ntemplate \\nvoid RH_RF95::setModeTx() {\\n if (this->_mode != RHGenericDriver::RHModeTx) {\\n this->write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_TX);\\n this->write(RH_RF95_REG_40_DIO_MAPPING1, 0x40); // Interrupt on TxDone\\n this->_mode = RHGenericDriver::RHModeTx;\\n }\\n}\\n\\n\\ntemplate \\nvoid RH_RF95::setTxPower(int8_t power, bool useRFO) {\\n // Sigh, different behaviours depending on whther the module use PA_BOOST or the RFO pin\\n // for the transmitter output\\n if (useRFO) {\\n if (power > 14) {\\n power = 14;\\n }\\n if (power < -1) {\\n power = -1;\\n }\\n this->write(RH_RF95_REG_09_PA_CONFIG, RH_RF95_MAX_POWER | (power + 1));\\n } else {\\n if (power > 23) {\\n power = 23;\\n }\\n if (power < 5) {\\n power = 5;\\n }\\n\\n // For RH_RF95_PA_DAC_ENABLE, manual says '+20dBm on PA_BOOST when OutputPower=0xf'\\n // RH_RF95_PA_DAC_ENABLE actually adds about 3dBm to all power levels. We will us it\\n // for 21 and 23dBm\\n if (power > 20) {\\n this->write(RH_RF95_REG_4D_PA_DAC, RH_RF95_PA_DAC_ENABLE);\\n power -= 3;\\n } else {\\n this->write(RH_RF95_REG_4D_PA_DAC, RH_RF95_PA_DAC_DISABLE);\\n }\\n\\n // RFM95/96/97/98 does not have RFO pins connected to anything. Only PA_BOOST\\n // pin is connected, so must use PA_BOOST\\n // Pout = 2 + OutputPower.\\n // The documentation is pretty confusing on this topic: PaSelect says the max power is 20dBm,\\n // but OutputPower claims it would be 17dBm.\\n // My measurements show 20dBm is correct\\n this->write(RH_RF95_REG_09_PA_CONFIG, RH_RF95_PA_SELECT | (power - 5));\\n }\\n}\\n\\n// Sets registers from a canned modem configuration structure\\ntemplate \\nvoid RH_RF95::setModemRegisters(const ModemConfig* config) {\\n this->write(RH_RF95_REG_1D_MODEM_CONFIG1, config->reg_1d);\\n this->write(RH_RF95_REG_1E_MODEM_CONFIG2, config->reg_1e);\\n this->write(RH_RF95_REG_26_MODEM_CONFIG3, config->reg_26);\\n}\\n\\n// Set one of the canned FSK Modem configs\\n// Returns true if its a valid choice\\ntemplate \\nbool RH_RF95::setModemConfig(ModemConfigChoice index) {\\n if (index > (signed int)(sizeof(MODEM_CONFIG_TABLE) / sizeof(ModemConfig))) {\\n return false;\\n }\\n\\n ModemConfig cfg;\\n memcpy_P(&cfg, &MODEM_CONFIG_TABLE[index], sizeof(ModemConfig));\\n setModemRegisters(&cfg);\\n\\n return true;\\n}\\n\\ntemplate \\nvoid RH_RF95::setPreambleLength(uint16_t bytes) {\\n this->write(RH_RF95_REG_20_PREAMBLE_MSB, bytes >> 8);\\n this->write(RH_RF95_REG_21_PREAMBLE_LSB, bytes & 0xff);\\n}\\n\\n#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE\\n template class RH_RF95;\\n#endif\\ntemplate class RH_RF95;\\n\\n#ifdef __AVR__\\n #include \\n template class RH_RF95;\\n#endif\" }", "{ filename: \"src/RH_RF95.h\", code: \"\\n\\n#ifndef RH_RF95_h\\n#define RH_RF95_h\\n\\n\\n#include \\\"RHUartDriver.h\\\"\\n\\n\\n#define RH_HAVE_SERIAL\\n\\n// Max number of octets the LORA Rx/Tx FIFO can hold\\n#define RH_RF95_FIFO_SIZE 255\\n\\n// This is the maximum number of bytes that can be carried by the LORA.\\n// We use some for headers, keeping fewer for RadioHead messages\\n#define RH_RF95_MAX_PAYLOAD_LEN RH_RF95_FIFO_SIZE\\n\\n// The length of the headers we add.\\n// The headers are inside the LORA's payload\\n#define RH_RF95_HEADER_LEN 4\\n\\n// This is the maximum message length that can be supported by this driver.\\n// Can be pre-defined to a smaller size (to save SRAM) prior to including this header\\n// Here we allow for 1 byte message length, 4 bytes headers, user data and 2 bytes of FCS\\n#ifndef RH_RF95_MAX_MESSAGE_LEN\\n #define RH_RF95_MAX_MESSAGE_LEN (RH_RF95_MAX_PAYLOAD_LEN - RH_RF95_HEADER_LEN)\\n#endif\\n\\n// The crystal oscillator frequency of the module\\n#define RH_RF95_FXOSC 32000000.0\\n\\n// The Frequency Synthesizer step = RH_RF95_FXOSC / 2^^19\\n#define RH_RF95_FSTEP (RH_RF95_FXOSC / 524288)\\n\\n\\n// Register names (LoRa Mode, from table 85)\\n#define RH_RF95_REG_00_FIFO 0x00\\n#define RH_RF95_REG_01_OP_MODE 0x01\\n#define RH_RF95_REG_02_RESERVED 0x02\\n#define RH_RF95_REG_03_RESERVED 0x03\\n#define RH_RF95_REG_04_RESERVED 0x04\\n#define RH_RF95_REG_05_RESERVED 0x05\\n#define RH_RF95_REG_06_FRF_MSB 0x06\\n#define RH_RF95_REG_07_FRF_MID 0x07\\n#define RH_RF95_REG_08_FRF_LSB 0x08\\n#define RH_RF95_REG_09_PA_CONFIG 0x09\\n#define RH_RF95_REG_0A_PA_RAMP 0x0a\\n#define RH_RF95_REG_0B_OCP 0x0b\\n#define RH_RF95_REG_0C_LNA 0x0c\\n#define RH_RF95_REG_0D_FIFO_ADDR_PTR 0x0d\\n#define RH_RF95_REG_0E_FIFO_TX_BASE_ADDR 0x0e\\n#define RH_RF95_REG_0F_FIFO_RX_BASE_ADDR 0x0f\\n#define RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR 0x10\\n#define RH_RF95_REG_11_IRQ_FLAGS_MASK 0x11\\n#define RH_RF95_REG_12_IRQ_FLAGS 0x12\\n#define RH_RF95_REG_13_RX_NB_BYTES 0x13\\n#define RH_RF95_REG_14_RX_HEADER_CNT_VALUE_MSB 0x14\\n#define RH_RF95_REG_15_RX_HEADER_CNT_VALUE_LSB 0x15\\n#define RH_RF95_REG_16_RX_PACKET_CNT_VALUE_MSB 0x16\\n#define RH_RF95_REG_17_RX_PACKET_CNT_VALUE_LSB 0x17\\n#define RH_RF95_REG_18_MODEM_STAT 0x18\\n#define RH_RF95_REG_19_PKT_SNR_VALUE 0x19\\n#define RH_RF95_REG_1A_PKT_RSSI_VALUE 0x1a\\n#define RH_RF95_REG_1B_RSSI_VALUE 0x1b\\n#define RH_RF95_REG_1C_HOP_CHANNEL 0x1c\\n#define RH_RF95_REG_1D_MODEM_CONFIG1 0x1d\\n#define RH_RF95_REG_1E_MODEM_CONFIG2 0x1e\\n#define RH_RF95_REG_1F_SYMB_TIMEOUT_LSB 0x1f\\n#define RH_RF95_REG_20_PREAMBLE_MSB 0x20\\n#define RH_RF95_REG_21_PREAMBLE_LSB 0x21\\n#define RH_RF95_REG_22_PAYLOAD_LENGTH 0x22\\n#define RH_RF95_REG_23_MAX_PAYLOAD_LENGTH 0x23\\n#define RH_RF95_REG_24_HOP_PERIOD 0x24\\n#define RH_RF95_REG_25_FIFO_RX_BYTE_ADDR 0x25\\n#define RH_RF95_REG_26_MODEM_CONFIG3 0x26\\n\\n#define RH_RF95_REG_40_DIO_MAPPING1 0x40\\n#define RH_RF95_REG_41_DIO_MAPPING2 0x41\\n#define RH_RF95_REG_42_VERSION 0x42\\n\\n#define RH_RF95_REG_4B_TCXO 0x4b\\n#define RH_RF95_REG_4D_PA_DAC 0x4d\\n#define RH_RF95_REG_5B_FORMER_TEMP 0x5b\\n#define RH_RF95_REG_61_AGC_REF 0x61\\n#define RH_RF95_REG_62_AGC_THRESH1 0x62\\n#define RH_RF95_REG_63_AGC_THRESH2 0x63\\n#define RH_RF95_REG_64_AGC_THRESH3 0x64\\n\\n// RH_RF95_REG_01_OP_MODE 0x01\\n#define RH_RF95_LONG_RANGE_MODE 0x80\\n#define RH_RF95_ACCESS_SHARED_REG 0x40\\n#define RH_RF95_MODE 0x07\\n#define RH_RF95_MODE_SLEEP 0x00\\n#define RH_RF95_MODE_STDBY 0x01\\n#define RH_RF95_MODE_FSTX 0x02\\n#define RH_RF95_MODE_TX 0x03\\n#define RH_RF95_MODE_FSRX 0x04\\n#define RH_RF95_MODE_RXCONTINUOUS 0x05\\n#define RH_RF95_MODE_RXSINGLE 0x06\\n#define RH_RF95_MODE_CAD 0x07\\n\\n// RH_RF95_REG_09_PA_CONFIG 0x09\\n#define RH_RF95_PA_SELECT 0x80\\n#define RH_RF95_MAX_POWER 0x70\\n#define RH_RF95_OUTPUT_POWER 0x0f\\n\\n// RH_RF95_REG_0A_PA_RAMP 0x0a\\n#define RH_RF95_LOW_PN_TX_PLL_OFF 0x10\\n#define RH_RF95_PA_RAMP 0x0f\\n#define RH_RF95_PA_RAMP_3_4MS 0x00\\n#define RH_RF95_PA_RAMP_2MS 0x01\\n#define RH_RF95_PA_RAMP_1MS 0x02\\n#define RH_RF95_PA_RAMP_500US 0x03\\n#define RH_RF95_PA_RAMP_250US 0x0\\n#define RH_RF95_PA_RAMP_125US 0x05\\n#define RH_RF95_PA_RAMP_100US 0x06\\n#define RH_RF95_PA_RAMP_62US 0x07\\n#define RH_RF95_PA_RAMP_50US 0x08\\n#define RH_RF95_PA_RAMP_40US 0x09\\n#define RH_RF95_PA_RAMP_31US 0x0a\\n#define RH_RF95_PA_RAMP_25US 0x0b\\n#define RH_RF95_PA_RAMP_20US 0x0c\\n#define RH_RF95_PA_RAMP_15US 0x0d\\n#define RH_RF95_PA_RAMP_12US 0x0e\\n#define RH_RF95_PA_RAMP_10US 0x0f\\n\\n// RH_RF95_REG_0B_OCP 0x0b\\n#define RH_RF95_OCP_ON 0x20\\n#define RH_RF95_OCP_TRIM 0x1f\\n\\n// RH_RF95_REG_0C_LNA 0x0c\\n#define RH_RF95_LNA_GAIN 0xe0\\n#define RH_RF95_LNA_BOOST 0x03\\n#define RH_RF95_LNA_BOOST_DEFAULT 0x00\\n#define RH_RF95_LNA_BOOST_150PC 0x11\\n\\n// RH_RF95_REG_11_IRQ_FLAGS_MASK 0x11\\n#define RH_RF95_RX_TIMEOUT_MASK 0x80\\n#define RH_RF95_RX_DONE_MASK 0x40\\n#define RH_RF95_PAYLOAD_CRC_ERROR_MASK 0x20\\n#define RH_RF95_VALID_HEADER_MASK 0x10\\n#define RH_RF95_TX_DONE_MASK 0x08\\n#define RH_RF95_CAD_DONE_MASK 0x04\\n#define RH_RF95_FHSS_CHANGE_CHANNEL_MASK 0x02\\n#define RH_RF95_CAD_DETECTED_MASK 0x01\\n\\n// RH_RF95_REG_12_IRQ_FLAGS 0x12\\n#define RH_RF95_RX_TIMEOUT 0x80\\n#define RH_RF95_RX_DONE 0x40\\n#define RH_RF95_PAYLOAD_CRC_ERROR 0x20\\n#define RH_RF95_VALID_HEADER 0x10\\n#define RH_RF95_TX_DONE 0x08\\n#define RH_RF95_CAD_DONE 0x04\\n#define RH_RF95_FHSS_CHANGE_CHANNEL 0x02\\n#define RH_RF95_CAD_DETECTED 0x01\\n\\n// RH_RF95_REG_18_MODEM_STAT 0x18\\n#define RH_RF95_RX_CODING_RATE 0xe0\\n#define RH_RF95_MODEM_STATUS_CLEAR 0x10\\n#define RH_RF95_MODEM_STATUS_HEADER_INFO_VALID 0x08\\n#define RH_RF95_MODEM_STATUS_RX_ONGOING 0x04\\n#define RH_RF95_MODEM_STATUS_SIGNAL_SYNCHRONIZED 0x02\\n#define RH_RF95_MODEM_STATUS_SIGNAL_DETECTED 0x01\\n\\n// RH_RF95_REG_1C_HOP_CHANNEL 0x1c\\n#define RH_RF95_PLL_TIMEOUT 0x80\\n#define RH_RF95_RX_PAYLOAD_CRC_IS_ON 0x40\\n#define RH_RF95_FHSS_PRESENT_CHANNEL 0x3f\\n\\n// RH_RF95_REG_1D_MODEM_CONFIG1 0x1d\\n#define RH_RF95_BW 0xc0\\n#define RH_RF95_BW_125KHZ 0x00\\n#define RH_RF95_BW_250KHZ 0x40\\n#define RH_RF95_BW_500KHZ 0x80\\n#define RH_RF95_BW_RESERVED 0xc0\\n#define RH_RF95_CODING_RATE 0x38\\n#define RH_RF95_CODING_RATE_4_5 0x00\\n#define RH_RF95_CODING_RATE_4_6 0x08\\n#define RH_RF95_CODING_RATE_4_7 0x10\\n#define RH_RF95_CODING_RATE_4_8 0x18\\n#define RH_RF95_IMPLICIT_HEADER_MODE_ON 0x04\\n#define RH_RF95_RX_PAYLOAD_CRC_ON 0x02\\n#define RH_RF95_LOW_DATA_RATE_OPTIMIZE 0x01\\n\\n// RH_RF95_REG_1E_MODEM_CONFIG2 0x1e\\n#define RH_RF95_SPREADING_FACTOR 0xf0\\n#define RH_RF95_SPREADING_FACTOR_64CPS 0x60\\n#define RH_RF95_SPREADING_FACTOR_128CPS 0x70\\n#define RH_RF95_SPREADING_FACTOR_256CPS 0x80\\n#define RH_RF95_SPREADING_FACTOR_512CPS 0x90\\n#define RH_RF95_SPREADING_FACTOR_1024CPS 0xa0\\n#define RH_RF95_SPREADING_FACTOR_2048CPS 0xb0\\n#define RH_RF95_SPREADING_FACTOR_4096CPS 0xc0\\n#define RH_RF95_TX_CONTINUOUS_MOE 0x08\\n#define RH_RF95_AGC_AUTO_ON 0x04\\n#define RH_RF95_SYM_TIMEOUT_MSB 0x03\\n\\n// RH_RF95_REG_4D_PA_DAC 0x4d\\n#define RH_RF95_PA_DAC_DISABLE 0x04\\n#define RH_RF95_PA_DAC_ENABLE 0x07\\n\\n/// Defines register values for a set of modem configuration registers\\n/// that can be passed to setModemRegisters() if none of the choices in\\n/// ModemConfigChoice suit your need setModemRegisters() writes the\\n/// register values from this structure to the appropriate registers\\n/// to set the desired spreading factor, coding rate and bandwidth\\ntypedef struct {\\n uint8_t reg_1d; ///< Value for register RH_RF95_REG_1D_MODEM_CONFIG1\\n uint8_t reg_1e; ///< Value for register RH_RF95_REG_1E_MODEM_CONFIG2\\n uint8_t reg_26; ///< Value for register RH_RF95_REG_26_MODEM_CONFIG3\\n} ModemConfig;\\n\\ntemplate\\nclass RH_RF95 : public RHUartDriver {\\n public:\\n\\n\\n /// Choices for setModemConfig() for a selected subset of common\\n /// data rates. If you need another configuration,\\n /// determine the necessary settings and call setModemRegisters() with your\\n /// desired settings. It might be helpful to use the LoRa calculator mentioned in\\n /// http://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf\\n /// These are indexes into MODEM_CONFIG_TABLE. We strongly recommend you use these symbolic\\n /// definitions and not their integer equivalents: its possible that new values will be\\n /// introduced in later versions (though we will try to avoid it).\\n typedef enum {\\n Bw125Cr45Sf128 = 0,\\t ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range\\n Bw500Cr45Sf128,\\t ///< Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range\\n Bw31_25Cr48Sf512,\\t ///< Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range\\n Bw125Cr48Sf4096, ///< Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. Slow+long range\\n } ModemConfigChoice;\\n\\n RH_RF95(T& ss);\\n\\n /// Initialise the Driver transport hardware and software.\\n /// Make sure the Driver is properly configured before calling init().\\n /// \\\\return true if initialisation succeeded.\\n virtual bool init();\\n\\n /// Prints the value of all chip registers\\n /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform\\n /// For debugging purposes only.\\n /// \\\\return true on success\\n bool printRegisters();\\n\\n /// Sets all the registered required to configure the data modem in the RF95/96/97/98, including the bandwidth,\\n /// spreading factor etc. You can use this to configure the modem with custom configurations if none of the\\n /// canned configurations in ModemConfigChoice suit you.\\n /// \\\\param[in] config A ModemConfig structure containing values for the modem configuration registers.\\n void setModemRegisters(const ModemConfig* config);\\n\\n /// Select one of the predefined modem configurations. If you need a modem configuration not provided\\n /// here, use setModemRegisters() with your own ModemConfig.\\n /// \\\\param[in] index The configuration choice.\\n /// \\\\return true if index is a valid choice.\\n bool setModemConfig(ModemConfigChoice index);\\n\\n /// Tests whether a new message is available\\n /// from the Driver.\\n /// On most drivers, this will also put the Driver into RHModeRx mode until\\n /// a message is actually received by the transport, when it wil be returned to RHModeIdle.\\n /// This can be called multiple times in a timeout loop\\n /// \\\\return true if a new, complete, error-free uncollected message is available to be retreived by recv()\\n virtual bool available();\\n\\n /// Turns the receiver on if it not already on.\\n /// If there is a valid message available, copy it to buf and return true\\n /// else return false.\\n /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).\\n /// You should be sure to call this function frequently enough to not miss any messages\\n /// It is recommended that you call it in your main loop.\\n /// \\\\param[in] buf Location to copy the received message\\n /// \\\\param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.\\n /// \\\\return true if a valid message was copied to buf\\n virtual bool recv(uint8_t* buf, uint8_t* len);\\n\\n /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().\\n /// Then loads a message into the transmitter and starts the transmitter. Note that a message length\\n /// of 0 is permitted.\\n /// \\\\param[in] data Array of data to be sent\\n /// \\\\param[in] len Number of bytes of data to send\\n /// \\\\return true if the message length was valid and it was correctly queued for transmit\\n virtual bool send(uint8_t* data, uint8_t len);\\n\\n /// Sets the length of the preamble\\n /// in bytes.\\n /// Caution: this should be set to the same\\n /// value on all nodes in your network. Default is 8.\\n /// Sets the message preamble length in RH_RF95_REG_??_PREAMBLE_?SB\\n /// \\\\param[in] bytes Preamble length in bytes.\\n void setPreambleLength(uint16_t bytes);\\n\\n /// Returns the maximum message length\\n /// available in this Driver.\\n /// \\\\return The maximum legal message length\\n virtual uint8_t maxMessageLength();\\n\\n /// Sets the transmitter and receiver\\n /// centre frequency.\\n /// \\\\param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution: RFM95/96/97/98 comes in several\\n /// different frequency ranges, and setting a frequency outside that range of your radio will probably not work\\n /// \\\\return true if the selected frquency centre is within range\\n bool setFrequency(float centre);\\n\\n /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running,\\n /// disables them.\\n void setModeIdle();\\n\\n /// If current mode is Tx or Idle, changes it to Rx.\\n /// Starts the receiver in the RF95/96/97/98.\\n void setModeRx();\\n\\n /// If current mode is Rx or Idle, changes it to Rx. F\\n /// Starts the transmitter in the RF95/96/97/98.\\n void setModeTx();\\n\\n /// Sets the transmitter power output level, and configures the transmitter pin.\\n /// Be a good neighbour and set the lowest power level you need.\\n /// Some SX1276/77/78/79 and compatible modules (such as RFM95/96/97/98)\\n /// use the PA_BOOST transmitter pin for high power output (and optionally the PA_DAC)\\n /// while some (such as the Modtronix inAir4 and inAir9)\\n /// use the RFO transmitter pin for lower power but higher efficiency.\\n /// You must set the appropriate power level and useRFO argument for your module.\\n /// Check with your module manufacturer which transmtter pin is used on your module\\n /// to ensure you are setting useRFO correctly.\\n /// Failure to do so will result in very low\\n /// transmitter power output.\\n /// Caution: legal power limits may apply in certain countries.\\n /// After init(), the power will be set to 13dBm, with useRFO false (ie PA_BOOST enabled).\\n /// \\\\param[in] power Transmitter power level in dBm. For RFM95/96/97/98 LORA with useRFO false,\\n /// valid values are from +5 to +23.\\n /// For Modtronix inAir4 and inAir9 with useRFO true (ie RFO pins in use),\\n /// valid values are from -1 to 14.\\n /// \\\\param[in] useRFO If true, enables the use of the RFO transmitter pins instead of\\n /// the PA_BOOST pin (false). Choose the correct setting for your module.\\n void setTxPower(int8_t power, bool useRFO = false);\\n\\n /// Sets the radio into low-power sleep mode.\\n /// If successful, the transport will stay in sleep mode until woken by\\n /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc)\\n /// Caution: there is a time penalty as the radio takes a finite time to wake from sleep mode.\\n /// \\\\return true if sleep mode was successfully entered.\\n virtual bool sleep();\\n\\n\\n\\n protected:\\n /// This is a low level function to handle the interrupts for one instance of RH_RF95.\\n /// Called automatically by isr*()\\n /// Should not need to be called by user code.\\n void handleInterrupt();\\n\\n /// Examine the revceive buffer to determine whether the message is for this node\\n void validateRxBuf();\\n\\n /// Clear our local receive buffer\\n void clearRxBuf();\\n\\n private:\\n /// Number of octets in the buffer\\n volatile uint8_t _bufLen;\\n\\n /// The receiver/transmitter buffer\\n uint8_t _buf[RH_RF95_MAX_PAYLOAD_LEN];\\n\\n /// True when there is a valid message in the buffer\\n volatile bool _rxBufValid;\\n};\\n\\n/// @example rf95_client.pde\\n/// @example rf95_server.pde\\n/// @example rf95_reliable_datagram_client.pde\\n/// @example rf95_reliable_datagram_server.pde\\n\\n#endif\\n\\n\" }", "{ filename: \"src/simulator.h\", code: \"// simulator.h\\n// Lets Arduino RadioHead sketches run within a simulator on Linux as a single process\\n// Copyright (C) 2014 Mike McCauley\\n// $Id: simulator.h,v 1.4 2015/08/13 02:45:47 mikem Exp mikem $\\n\\n#ifndef simulator_h\\n#define simulator_h\\n\\n#include \\n#include \\n#include \\n#include \\n\\n// Equivalent types for common Arduino types like uint8_t are in stdint.h\\n\\n// Access to some globals\\n// Command line args passed to the process.\\nextern int _simulator_argc;\\nextern char** _simulator_argv;\\n\\n// Definitions for various Arduino functions\\nextern void delay(unsigned long ms);\\nextern unsigned long millis();\\nextern long random(long to);\\nextern long random(long from, long to);\\n\\n// Equavalent to HardwareSerial in Arduino\\n// but outputs to stdout\\nclass SerialSimulator {\\n public:\\n#define DEC 10\\n#define HEX 16\\n#define OCT 8\\n#define BIN 2\\n\\n // TODO: move these from being inlined\\n void begin(int baud) {}\\n\\n size_t println(const char* s) {\\n print(s);\\n return printf(\\\"\\\\n\\\");\\n }\\n size_t print(const char* s) {\\n return printf(\\\"%s\\\", s); // This style prevent warnings from [-Wformat-security]\\n }\\n size_t print(unsigned int n, int base = DEC) {\\n if (base == DEC) {\\n return printf(\\\"%d\\\", n);\\n } else if (base == HEX) {\\n return printf(\\\"%02x\\\", n);\\n } else if (base == OCT) {\\n return printf(\\\"%o\\\", n);\\n }\\n // TODO: BIN\\n else {\\n return 0;\\n }\\n }\\n size_t print(char ch) {\\n return printf(\\\"%c\\\", ch);\\n }\\n size_t println(char ch) {\\n return printf(\\\"%c\\\\n\\\", ch);\\n }\\n size_t print(unsigned char ch, int base = DEC) {\\n return print((unsigned int)ch, base);\\n }\\n size_t println(unsigned char ch, int base = DEC) {\\n print((unsigned int)ch, base);\\n return printf(\\\"\\\\n\\\");\\n }\\n\\n};\\n\\n// Global instance of the Serial output\\nextern SerialSimulator Serial;\\n\\n#endif\\n\" }" ];PK :~TEsrc/facepanels.jsexport default {};PK :~T_[[src/exthandler.jsconst ExtHandler = { // when extension is loaded onLoad(app, target) {}, // when extension is unloaded onUnload(app) { // TODO }, // when device is connected onConnect(app, device) { // TODO }, // when device is disconnected onDisconnect(app, device) { // TODO }, // when stop button is clicked onStopAll(app, device) { // TODO }, // before switch to upload mode beforeChangeUploadMode(app, device) { // TODO return true; }, // before switch to debug mode beforeChangeDebugMode(app, device) { // TODO return true; }, // after switched to upload mode afterChangeUploadMode(app, device) { // TODO return true; }, // after switched to debug mode afterChangeDebugMode(app, device) { // TODO return true; }, // when device is selected onSelect(app, device) { // TODO }, // when device is unselected onUnselect(app, device) { // TODO }, // before upload code beforeCodeUpload(app, device) { // TODO }, // after code uploaded afterCodeUpload(app, device) { // TODO }, // when receiving and reading byte onRead(app, device) { // TODO } } export default ExtHandler;PK :~TBo=hEhEsrc/handlerProxy.jsself.rpc.CONFIG.TIMEOUT = 42000; self.rpc.CONFIG.HEARTBEAT = 4200; const __context = { app: self.rpc.remote.app, getDevice: function getDevice(deviceId) { return new Proxy({}, { get(target, name) { if (name == "id") { return deviceId; } return function (...args) { let runDevice = __context.app.runDevice; return runDevice(deviceId, name, ...args); }; } }); } }; !function (global) { "use strict"; var Op = Object.prototype; var hasOwn = Op.hasOwnProperty; var undefined; var $Symbol = typeof Symbol === "function" ? Symbol : {}; var iteratorSymbol = $Symbol.iterator || "@@iterator"; var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; var inModule = typeof module === "object"; var runtime = global.regeneratorRuntime; if (runtime) { if (inModule) { module.exports = runtime; } return; } runtime = global.regeneratorRuntime = inModule ? module.exports || {} : {}; function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; var generator = Object.create(protoGenerator.prototype); var context = new Context(tryLocsList || []); generator._invoke = makeInvokeMethod(innerFn, self, context); return generator; } runtime.wrap = wrap; function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } var GenStateSuspendedStart = "suspendedStart"; var GenStateSuspendedYield = "suspendedYield"; var GenStateExecuting = "executing"; var GenStateCompleted = "completed"; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; IteratorPrototype[iteratorSymbol] = function () { return this; }; var getProto = Object.getPrototypeOf; var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { IteratorPrototype = NativeIteratorPrototype; } var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; GeneratorFunctionPrototype.constructor = GeneratorFunction; GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = "GeneratorFunction"; function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { prototype[method] = function (arg) { return this._invoke(method, arg); }; }); } runtime.isGeneratorFunction = function (genFun) { var ctor = typeof genFun === "function" && genFun.constructor; return ctor ? ctor === GeneratorFunction || (ctor.displayName || ctor.name) === "GeneratorFunction" : false; }; runtime.mark = function (genFun) { if (Object.setPrototypeOf) { Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); } else { genFun.__proto__ = GeneratorFunctionPrototype; if (!(toStringTagSymbol in genFun)) { genFun[toStringTagSymbol] = "GeneratorFunction"; } } genFun.prototype = Object.create(Gp); return genFun; }; runtime.awrap = function (arg) { return { __await: arg }; }; function AsyncIterator(generator) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if (record.type === "throw") { reject(record.arg); } else { var result = record.arg; var value = result.value; if (value && typeof value === "object" && hasOwn.call(value, "__await")) { return Promise.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }); } return Promise.resolve(value).then(function (unwrapped) { result.value = unwrapped; resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } } var previousPromise; function enqueue(method, arg) { function callInvokeWithMethodAndArg() { return new Promise(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } this._invoke = enqueue; } defineIteratorMethods(AsyncIterator.prototype); AsyncIterator.prototype[asyncIteratorSymbol] = function () { return this; }; runtime.AsyncIterator = AsyncIterator; runtime.async = function (innerFn, outerFn, self, tryLocsList) { var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList)); return runtime.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }; function makeInvokeMethod(innerFn, self, context) { var state = GenStateSuspendedStart; return function invoke(method, arg) { if (state === GenStateExecuting) { throw new Error("Generator is already running"); } if (state === GenStateCompleted) { if (method === "throw") { throw arg; } return doneResult(); } context.method = method; context.arg = arg; while (true) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if (context.method === "next") { context.sent = context._sent = context.arg; } else if (context.method === "throw") { if (state === GenStateSuspendedStart) { state = GenStateCompleted; throw context.arg; } context.dispatchException(context.arg); } else if (context.method === "return") { context.abrupt("return", context.arg); } state = GenStateExecuting; var record = tryCatch(innerFn, self, context); if (record.type === "normal") { state = context.done ? GenStateCompleted : GenStateSuspendedYield; if (record.arg === ContinueSentinel) { continue; } return { value: record.arg, done: context.done }; } else if (record.type === "throw") { state = GenStateCompleted; context.method = "throw"; context.arg = record.arg; } } }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (method === undefined) { context.delegate = null; if (context.method === "throw") { if (delegate.iterator.return) { context.method = "return"; context.arg = undefined; maybeInvokeDelegate(delegate, context); if (context.method === "throw") { return ContinueSentinel; } } context.method = "throw"; context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if (record.type === "throw") { context.method = "throw"; context.arg = record.arg; context.delegate = null; return ContinueSentinel; } var info = record.arg; if (!info) { context.method = "throw"; context.arg = new TypeError("iterator result is not an object"); context.delegate = null; return ContinueSentinel; } if (info.done) { context[delegate.resultName] = info.value; context.next = delegate.nextLoc; if (context.method !== "return") { context.method = "next"; context.arg = undefined; } } else { return info; } context.delegate = null; return ContinueSentinel; } defineIteratorMethods(Gp); Gp[toStringTagSymbol] = "Generator"; Gp[iteratorSymbol] = function () { return this; }; Gp.toString = function () { return "[object Generator]"; }; function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; if (1 in locs) { entry.catchLoc = locs[1]; } if (2 in locs) { entry.finallyLoc = locs[2]; entry.afterLoc = locs[3]; } this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal"; delete record.arg; entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }]; tryLocsList.forEach(pushTryEntry, this); this.reset(true); } runtime.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } keys.reverse(); return function next() { while (keys.length) { var key = keys.pop(); if (key in object) { next.value = key; next.done = false; return next; } } next.done = true; return next; }; }; function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) { return iteratorMethod.call(iterable); } if (typeof iterable.next === "function") { return iterable; } if (!isNaN(iterable.length)) { var i = -1, next = function next() { while (++i < iterable.length) { if (hasOwn.call(iterable, i)) { next.value = iterable[i]; next.done = false; return next; } } next.value = undefined; next.done = true; return next; }; return next.next = next; } } return { next: doneResult }; } runtime.values = values; function doneResult() { return { value: undefined, done: true }; } Context.prototype = { constructor: Context, reset: function (skipTempReset) { this.prev = 0; this.next = 0; this.sent = this._sent = undefined; this.done = false; this.delegate = null; this.method = "next"; this.arg = undefined; this.tryEntries.forEach(resetTryEntry); if (!skipTempReset) { for (var name in this) { if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) { this[name] = undefined; } } } }, stop: function () { this.done = true; var rootEntry = this.tryEntries[0]; var rootRecord = rootEntry.completion; if (rootRecord.type === "throw") { throw rootRecord.arg; } return this.rval; }, dispatchException: function (exception) { if (this.done) { throw exception; } var context = this; function handle(loc, caught) { record.type = "throw"; record.arg = exception; context.next = loc; if (caught) { context.method = "next"; context.arg = undefined; } return !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; var record = entry.completion; if (entry.tryLoc === "root") { return handle("end"); } if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"); var hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true); } else if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc); } } else if (hasCatch) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true); } } else if (hasFinally) { if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc); } } else { throw new Error("try statement without catch or finally"); } } } }, abrupt: function (type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) { finallyEntry = null; } var record = finallyEntry ? finallyEntry.completion : {}; record.type = type; record.arg = arg; if (finallyEntry) { this.method = "next"; this.next = finallyEntry.finallyLoc; return ContinueSentinel; } return this.complete(record); }, complete: function (record, afterLoc) { if (record.type === "throw") { throw record.arg; } if (record.type === "break" || record.type === "continue") { this.next = record.arg; } else if (record.type === "return") { this.rval = this.arg = record.arg; this.method = "return"; this.next = "end"; } else if (record.type === "normal" && afterLoc) { this.next = afterLoc; } return ContinueSentinel; }, finish: function (finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) { this.complete(entry.completion, entry.afterLoc); resetTryEntry(entry); return ContinueSentinel; } } }, "catch": function (tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if (record.type === "throw") { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function (iterable, resultName, nextLoc) { this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }; if (this.method === "next") { this.arg = undefined; } return ContinueSentinel; } }; }(function () { return this || typeof self === "object" && self; }() || Function("return this")()); const disableBlocks = { debug: [], upload: [] }; const mustLoginBlocks = []; const triggerBlocksStatus = async (mode, app) => {}; const blockHandlers = { 'BLOCK_1653809874148': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653809874506': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653809874838': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653809875114': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653809875483': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653809875786': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653809876062': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653809876310': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653809876594': { onRun: (args, app, device, block) => {} } }; const ExtHandler = { onLoad(app, target) {}, onUnload(app) {}, onConnect(app, device) {}, onDisconnect(app, device) {}, onStopAll(app, device) {}, beforeChangeUploadMode(app, device) { return true; }, beforeChangeDebugMode(app, device) { return true; }, afterChangeUploadMode(app, device) { return true; }, afterChangeDebugMode(app, device) { return true; }, onSelect(app, device) {}, onUnselect(app, device) {}, beforeCodeUpload(app, device) {}, afterCodeUpload(app, device) {}, onRead(app, device) {} }; self.rpc.exports = { runBlock: function runBlock(opcode, method, deviceId, block, args) { var blockHandler = blockHandlers[opcode]; if (!blockHandler) { console.error('cannot find opcode of ' + opcode); return null; } var handle = blockHandler[method]; let app = __context.app; let device = __context.getDevice(deviceId); if (method === 'onRun') { return handle(args, app, device, block); } else { return handle(app, device, block); } }, runExtension: function runExtension(srcMethod, deviceId) { var method = ExtHandler[srcMethod]; if (!method) { console.error('method of ' + srcMethod + ' is no valid'); return null; } let app = __context.app; if (deviceId) { let device = __context.getDevice(deviceId); return method(app, device); } else { return method(app); } } };PK :~T src/cates/PK :~Tsrc/cates/cate_25f02c8a/PK :~T3 src/cates/cate_25f02c8a/index.jsimport blocks from './blocks.js'; const cate_25f02c8a = (facepanels) => ({ "name": "cate_25f02c8a", "colors": [ "#42CCFF", "#22C3FF", "#02BBFF" ], "menuIconURI": "", "blockIcon": { "type": "image", "width": 28, "height": 26, "src": window.MbApi.getExtResPath('vdr_grove_lora/imgs/48687157c9ad4d6fa1243bebe8e94267.png', 'vdr_grove_lora') }, "blocks": blocks(facepanels), "menus": { "BLOCK_1653809874148_FREQUENCE": [{ "text": "BLOCK_1653809874148_FREQUENCE_0", "value": "433.0" }, { "text": "BLOCK_1653809874148_FREQUENCE_1", "value": "868.0" } ], "BLOCK_1653809874148_PINDIGIT": [{ "text": "BLOCK_1653809874148_PINDIGIT_0", "value": "2" }, { "text": "BLOCK_1653809874148_PINDIGIT_1", "value": "3" }, { "text": "BLOCK_1653809874148_PINDIGIT_2", "value": "4" }, { "text": "BLOCK_1653809874148_PINDIGIT_3", "value": "5" }, { "text": "BLOCK_1653809874148_PINDIGIT_4", "value": "6" }, { "text": "BLOCK_1653809874148_PINDIGIT_5", "value": "7" }, { "text": "BLOCK_1653809874148_PINDIGIT_6", "value": "8" } ], "BLOCK_1653809874148_NBDATA": [{ "text": "BLOCK_1653809874148_NBDATA_0", "value": "5" }, { "text": "BLOCK_1653809874148_NBDATA_1", "value": "10" }, { "text": "BLOCK_1653809874148_NBDATA_2", "value": "15" }, { "text": "BLOCK_1653809874148_NBDATA_3", "value": "20" }, { "text": "BLOCK_1653809874148_NBDATA_4", "value": "0" } ] } }); export default cate_25f02c8a;PK :~T?osrc/cates/index.jsimport cate_25f02c8a from './cate_25f02c8a/index.js'; const cates = (facepanels) => ([ cate_25f02c8a(facepanels) ]); export default cates;PK :~T[$DD!src/cates/cate_25f02c8a/blocks.jsconst blocks = (extFacePanels) => ([{ "opcode": "BLOCK_1653809874148", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "frequence": { "type": "fieldMenu", "defaultValue": "433.0", "menu": "BLOCK_1653809874148_FREQUENCE" }, "pinDigit": { "type": "fieldMenu", "defaultValue": "2", "menu": "BLOCK_1653809874148_PINDIGIT" }, "nbData": { "type": "fieldMenu", "defaultValue": "5", "menu": "BLOCK_1653809874148_NBDATA" } }, "branchCount": 0, "codes": { "arduinoc": { "sections": { "include": [ "\"src/RH_RF95.h\"" ], "declare": `SoftwareSerial LoraSerial(/*{pinDigit}*/, /*{pinDigit}*/ + 1);\r\nRH_RF95 rf95(LoraSerial);\r\n\r\nString rf95sData;\r\nconst int rf95nbData = /*{nbData}*/; \r\nfloat rf95fDatas[rf95nbData];\r\n\r\nvoid rf95resetFDatas(){\r\n for ( int i = 0 ; i < rf95nbData ; i++ ) {\r\n rf95fDatas[i]=0;\r\n }\r\n}\r`, "setup": ` while (!rf95.init()) {\r\n }\r\n rf95.setFrequency(/*{frequence}*/);` } } }, "handler": this.funcs.BLOCK_1653809874148 }, { "opcode": "BLOCK_1653809874506", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "index": { "type": "number", "defaultValue": 1 }, "data": { "type": "number", "defaultValue": 10 } }, "branchCount": 0, "codes": { "arduinoc": { "code": `rf95setFDatas(/*{index}*/,/*{data}*/);`, "sections": { "declare": `void rf95setFDatas(int i, float data){\r\n if ((i>=0) && (i=0) && (i\n// codes make you happy\n\n//( include //)\n#include \n//( lib //)\n\n//({\n this.$ALL_VARIABLES.length==0?'':this.$ALL_VARIABLES.map(v=>\"float \"+v+\" = 0;\").join('\\\\n')\n}//)\n\n//( declare //)\n\n\nvoid _delay(float seconds) {\n long endTime = millis() + seconds * 1000;\n while(millis() < endTime) _loop();\n}\n\n//(\nvoid setup() {\n //( setup //)\n //( code //)\n}\n//)\n\nvoid _loop() {\n //( _loop //)\n}\n\nvoid loop() {\n _loop();\n}", "generator": "({\n lang: 'arduinoc',\n template: `<%=template%>`,\n splitor: {\n frame: {\n left: \"//(\",\n right: \"//)\",\n },\n expression: {\n left: \"/*{\",\n right: \"}*/\",\n }\n },\n reducers: [\n {\n name: 'include',\n reduce: (codes) => {\n let codes1 = []\n for (let code of codes) {\n let codeStr = '';\n if (typeof code === 'string') {\n codeStr = code;\n } else if (typeof code === 'function') {\n codeStr = code();\n }\n if (codes1.indexOf(codeStr) === -1) {\n codes1.push(codeStr);\n }\n }\n if (codes1.length === 0) {\n return undefined;\n }\n return codes1.map(code => {\n return '#include ' + code;\n }).join('\\n') + '\\n'\n }\n }\n ]\n})", "snippets": "", "sources": [ { "name": "src/atomic.h", "url": "src/atomic.h", "fileData": "/*\n This is port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3\n v1.0\n Mark Pendrith, Nov 27, 2012.\n\n From Mark:\n >When I ported the macros I emailed Dean to ask what attribution would be\n >appropriate, and here is his response:\n >\n >>Mark,\n >>I think it's great that you've ported the macros; consider them\n >>public domain, to do with whatever you wish. I hope you find them >useful .\n >>\n >>Cheers!\n >>- Dean\n*/\n\n#ifdef __arm__\n#ifndef _CORTEX_M3_ATOMIC_H_\n#define _CORTEX_M3_ATOMIC_H_\n\nstatic __inline__ uint32_t __get_primask(void) \\\n{\n uint32_t primask = 0; \\\n __asm__ volatile(\"MRS %[result], PRIMASK\\n\\t\":[result]\"=r\"(primask)::); \\\n return primask;\n} // returns 0 if interrupts enabled, 1 if disabled\n\nstatic __inline__ void __set_primask(uint32_t setval) \\\n{\n __asm__ volatile(\"MSR PRIMASK, %[value]\\n\\t\"\"dmb\\n\\t\"\"dsb\\n\\t\"\"isb\\n\\t\"::[value]\"r\"(setval):);\n __asm__ volatile(\"\" ::: \"memory\");\n}\n\nstatic __inline__ uint32_t __iSeiRetVal(void) \\\n{\n __asm__ volatile(\"CPSIE i\\n\\t\"\"dmb\\n\\t\"\"dsb\\n\\t\"\"isb\\n\\t\"); \\\n __asm__ volatile(\"\" ::: \"memory\"); return 1;\n}\n\nstatic __inline__ uint32_t __iCliRetVal(void) \\\n{\n __asm__ volatile(\"CPSID i\\n\\t\"\"dmb\\n\\t\"\"dsb\\n\\t\"\"isb\\n\\t\"); \\\n __asm__ volatile(\"\" ::: \"memory\"); return 1;\n}\n\nstatic __inline__ void __iSeiParam(const uint32_t* __s) \\\n{\n __asm__ volatile(\"CPSIE i\\n\\t\"\"dmb\\n\\t\"\"dsb\\n\\t\"\"isb\\n\\t\"); \\\n __asm__ volatile(\"\" ::: \"memory\"); (void)__s;\n}\n\nstatic __inline__ void __iCliParam(const uint32_t* __s) \\\n{\n __asm__ volatile(\"CPSID i\\n\\t\"\"dmb\\n\\t\"\"dsb\\n\\t\"\"isb\\n\\t\"); \\\n __asm__ volatile(\"\" ::: \"memory\"); (void)__s;\n}\n\nstatic __inline__ void __iRestore(const uint32_t* __s) \\\n{\n __set_primask(*__s); __asm__ volatile(\"dmb\\n\\t\"\"dsb\\n\\t\"\"isb\\n\\t\"); \\\n __asm__ volatile(\"\" ::: \"memory\");\n}\n\n\n#define ATOMIC_BLOCK(type) \\\n for ( type, __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0 )\n\n#define ATOMIC_RESTORESTATE \\\n uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask()\n\n#define ATOMIC_FORCEON \\\n uint32_t primask_save __attribute__((__cleanup__(__iSeiParam))) = 0\n\n#define NONATOMIC_BLOCK(type) \\\n for ( type, __ToDo = __iSeiRetVal(); __ToDo ; __ToDo = 0 )\n\n#define NONATOMIC_RESTORESTATE \\\n uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask()\n\n#define NONATOMIC_FORCEOFF \\\n uint32_t primask_save __attribute__((__cleanup__(__iCliParam))) = 0\n\n#endif\n#endif\n" }, { "name": "src/RadioHead.h", "url": "src/RadioHead.h", "fileData": "#ifndef RadioHead_h\n#define RadioHead_h\n\n// Official version numbers are maintained automatically by Makefile:\n#define RH_VERSION_MAJOR 1\n#define RH_VERSION_MINOR 57\n\n// Symbolic names for currently supported platform types\n#define RH_PLATFORM_ARDUINO 1\n#define RH_PLATFORM_MSP430 2\n#define RH_PLATFORM_STM32 3\n#define RH_PLATFORM_GENERIC_AVR8 4\n#define RH_PLATFORM_UNO32 5\n#define RH_PLATFORM_UNIX 6\n#define RH_PLATFORM_STM32STD 7\n#define RH_PLATFORM_STM32F4_HAL 8\n#define RH_PLATFORM_RASPI 9\n#define RH_PLATFORM_NRF51 10\n#define RH_PLATFORM_ESP8266 11\n#define RH_PLATFORM_STM32F2 12\n\n////////////////////////////////////////////////////\n// Select platform automatically, if possible\n#ifndef RH_PLATFORM\n #if defined(MPIDE)\n #define RH_PLATFORM RH_PLATFORM_UNO32\n #elif defined(NRF51)\n #define RH_PLATFORM RH_PLATFORM_NRF51\n #elif defined(ESP8266)\n #define RH_PLATFORM RH_PLATFORM_ESP8266\n #elif defined(ARDUINO)\n #define RH_PLATFORM RH_PLATFORM_ARDUINO\n #elif defined(__MSP430G2452__) || defined(__MSP430G2553__)\n #define RH_PLATFORM RH_PLATFORM_MSP430\n #elif defined(MCU_STM32F103RE)\n #define RH_PLATFORM RH_PLATFORM_STM32\n #elif defined(STM32F2XX)\n #define RH_PLATFORM RH_PLATFORM_STM32F2\n #elif defined(USE_STDPERIPH_DRIVER)\n #define RH_PLATFORM RH_PLATFORM_STM32STD\n #elif defined(RASPBERRY_PI)\n #define RH_PLATFORM RH_PLATFORM_RASPI\n #elif defined(__unix__) // Linux\n #define RH_PLATFORM RH_PLATFORM_UNIX\n #elif defined(__APPLE__) // OSX\n #define RH_PLATFORM RH_PLATFORM_UNIX\n #else\n #error Platform not defined!\n #endif\n#endif\n\n#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtinyX4__) || defined(__AVR_ATtinyX5__) || defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny4313__) || defined(__AVR_ATtinyX313__)\n #define RH_PLATFORM_ATTINY\n#endif\n\n////////////////////////////////////////////////////\n// Platform specific headers:\n#if (RH_PLATFORM == RH_PLATFORM_ARDUINO)\n #if (ARDUINO >= 100)\n #include \n #endif\n#endif\n\n////////////////////////////////////////////////////\n// This is an attempt to make a portable atomic block\n#if (RH_PLATFORM == RH_PLATFORM_ARDUINO)\n #if defined(__arm__)\n #include \n #endif\n #define ATOMIC_BLOCK_START ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {\n #define ATOMIC_BLOCK_END }\n#endif\n\n////////////////////////////////////////////////////\n// Try to be compatible with systems that support yield() and multitasking\n// instead of spin-loops\n// Recent Arduino IDE or Teensy 3 has yield()\n#if (RH_PLATFORM == RH_PLATFORM_ARDUINO && ARDUINO >= 155 && !defined(RH_PLATFORM_ATTINY)) || (TEENSYDUINO && defined(__MK20DX128__))\n #define YIELD yield();\n#endif\n\n////////////////////////////////////////////////////\n// digitalPinToInterrupt is not available prior to Arduino 1.5.6 and 1.0.6\n// See http://arduino.cc/en/Reference/attachInterrupt\n#ifndef NOT_AN_INTERRUPT\n #define NOT_AN_INTERRUPT -1\n#endif\n#ifndef digitalPinToInterrupt\n\n // All other arduino except Due:\n // Serial Arduino, Extreme, NG, BT, Uno, Diecimila, Duemilanove, Nano, Menta, Pro, Mini 04, Fio, LilyPad, Ethernet etc\n // 2->0, 3->1\n #define digitalPinToInterrupt(p) ((p) == 2 ? 0 : ((p) == 3 ? 1 : NOT_AN_INTERRUPT))\n\n#endif\n\n// On some platforms, attachInterrupt() takes a pin number, not an interrupt number\n#if (RH_PLATFORM == RH_PLATFORM_ARDUINO) && defined (__arm__) && (defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_SAM_DUE))\n #define RH_ATTACHINTERRUPT_TAKES_PIN_NUMBER\n#endif\n\n// Slave select pin, some platforms such as ATTiny do not define it.\n#ifndef SS\n #define SS 10\n#endif\n\n// These defs cause trouble on some versions of Arduino\n#undef abs\n#undef round\n#undef double\n\n// Sigh: there is no widespread adoption of htons and friends in the base code, only in some WiFi headers etc\n// that have a lot of excess baggage\n#if RH_PLATFORM != RH_PLATFORM_UNIX && !defined(htons)\n// #ifndef htons\n// These predefined macros availble on modern GCC compilers\n#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n// Atmel processors\n#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) )\n#define ntohs(x) htons(x)\n#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \\\n ((x)<< 8 & 0x00FF0000UL) | \\\n ((x)>> 8 & 0x0000FF00UL) | \\\n ((x)>>24 & 0x000000FFUL) )\n#define ntohl(x) htonl(x)\n\n#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__\n// Others\n#define htons(x) (x)\n#define ntohs(x) (x)\n#define htonl(x) (x)\n#define ntohl(x) (x)\n\n#else\n#error \"Dont know how to define htons and friends for this processor\"\n#endif\n#endif\n\n// This is the address that indicates a broadcast\n#define RH_BROADCAST_ADDRESS 0xff\n\n#endif\n" }, { "name": "src/RHGenericDriver.cpp", "url": "src/RHGenericDriver.cpp", "fileData": "// RHGenericDriver.cpp\n//\n// Copyright (C) 2014 Mike McCauley\n// $Id: RHGenericDriver.cpp,v 1.19 2015/12/11 01:10:24 mikem Exp $\n\n#include \"RHGenericDriver.h\"\n\nRHGenericDriver::RHGenericDriver()\n :\n _mode(RHModeInitialising),\n _thisAddress(RH_BROADCAST_ADDRESS),\n _txHeaderTo(RH_BROADCAST_ADDRESS),\n _txHeaderFrom(RH_BROADCAST_ADDRESS),\n _txHeaderId(0),\n _txHeaderFlags(0),\n _rxBad(0),\n _rxGood(0),\n _txGood(0) {\n}\n\nbool RHGenericDriver::init() {\n return true;\n}\n\n// Blocks until a valid message is received\nvoid RHGenericDriver::waitAvailable() {\n while (!available()) {\n YIELD;\n }\n}\n\n// Blocks until a valid message is received or timeout expires\n// Return true if there is a message available\n// Works correctly even on millis() rollover\nbool RHGenericDriver::waitAvailableTimeout(uint16_t timeout) {\n unsigned long starttime = millis();\n while ((millis() - starttime) < timeout) {\n if (available()) {\n return true;\n }\n YIELD;\n }\n return false;\n}\n\nbool RHGenericDriver::waitPacketSent() {\n while (_mode == RHModeTx) {\n available();\n YIELD; // Wait for any previous transmit to finish\n }\n\n return true;\n}\n\nbool RHGenericDriver::waitPacketSent(uint16_t timeout) {\n unsigned long starttime = millis();\n while ((millis() - starttime) < timeout) {\n if (_mode != RHModeTx) { // Any previous transmit finished?\n return true;\n }\n available();\n YIELD;\n }\n return false;\n}\n\nvoid RHGenericDriver::setPromiscuous(bool promiscuous) {\n _promiscuous = promiscuous;\n}\n\nvoid RHGenericDriver::setThisAddress(uint8_t address) {\n _thisAddress = address;\n}\n\nvoid RHGenericDriver::setHeaderTo(uint8_t to) {\n _txHeaderTo = to;\n}\n\nvoid RHGenericDriver::setHeaderFrom(uint8_t from) {\n _txHeaderFrom = from;\n}\n\nvoid RHGenericDriver::setHeaderId(uint8_t id) {\n _txHeaderId = id;\n}\n\nvoid RHGenericDriver::setHeaderFlags(uint8_t set, uint8_t clear) {\n _txHeaderFlags &= ~clear;\n _txHeaderFlags |= set;\n}\n\nuint8_t RHGenericDriver::headerTo() {\n return _rxHeaderTo;\n}\n\nuint8_t RHGenericDriver::headerFrom() {\n return _rxHeaderFrom;\n}\n\nuint8_t RHGenericDriver::headerId() {\n return _rxHeaderId;\n}\n\nuint8_t RHGenericDriver::headerFlags() {\n return _rxHeaderFlags;\n}\n\nint8_t RHGenericDriver::lastRssi() {\n return _lastRssi;\n}\n\nRHGenericDriver::RHMode RHGenericDriver::mode() {\n return _mode;\n}\n\nvoid RHGenericDriver::setMode(RHMode mode) {\n _mode = mode;\n}\n\nbool RHGenericDriver::sleep() {\n return false;\n}\n\n// Diagnostic help\nvoid RHGenericDriver::printBuffer(const char* prompt, const uint8_t* buf, uint8_t len) {\n uint8_t i;\n\n #ifdef RH_HAVE_SERIAL\n Serial.println(prompt);\n for (i = 0; i < len; i++) {\n if (i % 16 == 15) {\n Serial.println(buf[i], HEX);\n } else {\n Serial.print(buf[i], HEX);\n Serial.print(' ');\n }\n }\n Serial.println(\"\");\n #endif\n}\n\nuint16_t RHGenericDriver::rxBad() {\n return _rxBad;\n}\n\nuint16_t RHGenericDriver::rxGood() {\n return _rxGood;\n}\n\nuint16_t RHGenericDriver::txGood() {\n return _txGood;\n}\n\n#if (RH_PLATFORM == RH_PLATFORM_ARDUINO) && defined(RH_PLATFORM_ATTINY)\n// Tinycore does not have __cxa_pure_virtual, so without this we\n// get linking complaints from the default code generated for pure virtual functions\nextern \"C\" void __cxa_pure_virtual() {\n while (1);\n}\n#endif\n" }, { "name": "src/RHGenericDriver.h", "url": "src/RHGenericDriver.h", "fileData": "// RHGenericDriver.h\n// Author: Mike McCauley (mikem@airspayce.com)\n// Copyright (C) 2014 Mike McCauley\n// $Id: RHGenericDriver.h,v 1.16 2015/01/02 21:38:24 mikem Exp $\n\n#ifndef RHGenericDriver_h\n#define RHGenericDriver_h\n\n#include \"RadioHead.h\"\n\n// Defines bits of the FLAGS header reserved for use by the RadioHead library and\n// the flags available for use by applications\n#define RH_FLAGS_RESERVED 0xf0\n#define RH_FLAGS_APPLICATION_SPECIFIC 0x0f\n#define RH_FLAGS_NONE 0\n\n/////////////////////////////////////////////////////////////////////\n/// \\class RHGenericDriver RHGenericDriver.h \n/// \\brief Abstract base class for a RadioHead driver.\n///\n/// This class defines the functions that must be provided by any RadioHead driver.\n/// Different types of driver will implement all the abstract functions, and will perhaps override\n/// other functions in this subclass, or perhaps add new functions specifically required by that driver.\n/// Do not directly instantiate this class: it is only to be subclassed by driver classes.\n///\n/// Subclasses are expected to implement a half-duplex, unreliable, error checked, unaddressed packet transport.\n/// They are expected to carry a message payload with an appropriate maximum length for the transport hardware\n/// and to also carry unaltered 4 message headers: TO, FROM, ID, FLAGS\n///\n/// \\par Headers\n///\n/// Each message sent and received by a RadioHead driver includes 4 headers:\n/// -TO The node address that the message is being sent to (broadcast RH_BROADCAST_ADDRESS (255) is permitted)\n/// -FROM The node address of the sending node\n/// -ID A message ID, distinct (over short time scales) for each message sent by a particilar node\n/// -FLAGS A bitmask of flags. The most significant 4 bits are reserved for use by RadioHead. The least\n/// significant 4 bits are reserved for applications.\nclass RHGenericDriver {\n public:\n /// \\brief Defines different operating modes for the transport hardware\n ///\n /// These are the different values that can be adopted by the _mode variable and\n /// returned by the mode() member function,\n typedef enum {\n RHModeInitialising = 0, ///< Transport is initialising. Initial default value until init() is called..\n RHModeSleep, ///< Transport hardware is in low power sleep mode (if supported)\n RHModeIdle, ///< Transport is idle.\n RHModeTx, ///< Transport is in the process of transmitting a message.\n RHModeRx ///< Transport is in the process of receiving a message.\n } RHMode;\n\n /// Constructor\n RHGenericDriver();\n\n /// Initialise the Driver transport hardware and software.\n /// Make sure the Driver is properly configured before calling init().\n /// \\return true if initialisation succeeded.\n virtual bool init();\n\n /// Tests whether a new message is available\n /// from the Driver.\n /// On most drivers, if there is an uncollected received message, and there is no message\n /// currently bing transmitted, this will also put the Driver into RHModeRx mode until\n /// a message is actually received by the transport, when it will be returned to RHModeIdle.\n /// This can be called multiple times in a timeout loop.\n /// \\return true if a new, complete, error-free uncollected message is available to be retreived by recv().\n virtual bool available() = 0;\n //virtual bool available(){};\n\n /// Turns the receiver on if it not already on.\n /// If there is a valid message available, copy it to buf and return true\n /// else return false.\n /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).\n /// You should be sure to call this function frequently enough to not miss any messages\n /// It is recommended that you call it in your main loop.\n /// \\param[in] buf Location to copy the received message\n /// \\param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.\n /// \\return true if a valid message was copied to buf\n virtual bool recv(uint8_t* buf, uint8_t* len) = 0;\n //virtual bool recv(uint8_t* buf, uint8_t* len){};\n\n /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().\n /// Then loads a message into the transmitter and starts the transmitter. Note that a message length\n /// of 0 is NOT permitted. If the message is too long for the underlying radio technology, send() will\n /// return false and will not send the message.\n /// \\param[in] data Array of data to be sent\n /// \\param[in] len Number of bytes of data to send (> 0)\n /// \\return true if the message length was valid and it was correctly queued for transmit\n virtual bool send(uint8_t* data, uint8_t len) = 0;\n //virtual bool send(uint8_t* data, uint8_t len){};\n\n /// Returns the maximum message length\n /// available in this Driver.\n /// \\return The maximum legal message length\n virtual uint8_t maxMessageLength() = 0;\n //virtual uint8_t maxMessageLength(){};\n\n /// Starts the receiver and blocks until a valid received\n /// message is available.\n virtual void waitAvailable();\n\n /// Blocks until the transmitter\n /// is no longer transmitting.\n virtual bool waitPacketSent();\n\n /// Blocks until the transmitter is no longer transmitting.\n /// or until the timeout occuers, whichever happens first\n /// \\param[in] timeout Maximum time to wait in milliseconds.\n /// \\return true if the RF22 completed transmission within the timeout period. False if it timed out.\n virtual bool waitPacketSent(uint16_t timeout);\n\n /// Starts the receiver and blocks until a received message is available or a timeout\n /// \\param[in] timeout Maximum time to wait in milliseconds.\n /// \\return true if a message is available\n virtual bool waitAvailableTimeout(uint16_t timeout);\n\n /// Sets the address of this node. Defaults to 0xFF. Subclasses or the user may want to change this.\n /// This will be used to test the adddress in incoming messages. In non-promiscuous mode,\n /// only messages with a TO header the same as thisAddress or the broadcast addess (0xFF) will be accepted.\n /// In promiscuous mode, all messages will be accepted regardless of the TO header.\n /// In a conventional multinode system, all nodes will have a unique address\n /// (which you could store in EEPROM).\n /// You would normally set the header FROM address to be the same as thisAddress (though you dont have to,\n /// allowing the possibilty of address spoofing).\n /// \\param[in] thisAddress The address of this node.\n virtual void setThisAddress(uint8_t thisAddress);\n\n /// Sets the TO header to be sent in all subsequent messages\n /// \\param[in] to The new TO header value\n virtual void setHeaderTo(uint8_t to);\n\n /// Sets the FROM header to be sent in all subsequent messages\n /// \\param[in] from The new FROM header value\n virtual void setHeaderFrom(uint8_t from);\n\n /// Sets the ID header to be sent in all subsequent messages\n /// \\param[in] id The new ID header value\n virtual void setHeaderId(uint8_t id);\n\n /// Sets and clears bits in the FLAGS header to be sent in all subsequent messages\n /// First it clears he FLAGS according to the clear argument, then sets the flags according to the\n /// set argument. The default for clear always clears the application specific flags.\n /// \\param[in] set bitmask of bits to be set. Flags are cleared with the clear mask before being set.\n /// \\param[in] clear bitmask of flags to clear. Defaults to RH_FLAGS_APPLICATION_SPECIFIC\n /// which clears the application specific flags, resulting in new application specific flags\n /// identical to the set.\n virtual void setHeaderFlags(uint8_t set, uint8_t clear = RH_FLAGS_APPLICATION_SPECIFIC);\n\n /// Tells the receiver to accept messages with any TO address, not just messages\n /// addressed to thisAddress or the broadcast address\n /// \\param[in] promiscuous true if you wish to receive messages with any TO address\n virtual void setPromiscuous(bool promiscuous);\n\n /// Returns the TO header of the last received message\n /// \\return The TO header\n virtual uint8_t headerTo();\n\n /// Returns the FROM header of the last received message\n /// \\return The FROM header\n virtual uint8_t headerFrom();\n\n /// Returns the ID header of the last received message\n /// \\return The ID header\n virtual uint8_t headerId();\n\n /// Returns the FLAGS header of the last received message\n /// \\return The FLAGS header\n virtual uint8_t headerFlags();\n\n /// Returns the most recent RSSI (Receiver Signal Strength Indicator).\n /// Usually it is the RSSI of the last received message, which is measured when the preamble is received.\n /// If you called readRssi() more recently, it will return that more recent value.\n /// \\return The most recent RSSI measurement in dBm.\n int8_t lastRssi();\n\n /// Returns the operating mode of the library.\n /// \\return the current mode, one of RF69_MODE_*\n RHMode mode();\n\n /// Sets the operating mode of the transport.\n void setMode(RHMode mode);\n\n /// Sets the transport hardware into low-power sleep mode\n /// (if supported). May be overridden by specific drivers to initialte sleep mode.\n /// If successful, the transport will stay in sleep mode until woken by\n /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc)\n /// \\return true if sleep mode is supported by transport hardware and the RadioHead driver, and if sleep mode\n /// was successfully entered. If sleep mode is not suported, return false.\n virtual bool sleep();\n\n /// Prints a data buffer in HEX.\n /// For diagnostic use\n /// \\param[in] prompt string to preface the print\n /// \\param[in] buf Location of the buffer to print\n /// \\param[in] len Length of the buffer in octets.\n static void printBuffer(const char* prompt, const uint8_t* buf, uint8_t len);\n\n /// Returns the count of the number of bad received packets (ie packets with bad lengths, checksum etc)\n /// which were rejected and not delivered to the application.\n /// Caution: not all drivers can correctly report this count. Some underlying hardware only report\n /// good packets.\n /// \\return The number of bad packets received.\n uint16_t rxBad();\n\n /// Returns the count of the number of\n /// good received packets\n /// \\return The number of good packets received.\n uint16_t rxGood();\n\n /// Returns the count of the number of\n /// packets successfully transmitted (though not necessarily received by the destination)\n /// \\return The number of packets successfully transmitted\n uint16_t txGood();\n\n protected:\n\n /// The current transport operating mode\n volatile RHMode _mode;\n\n /// This node id\n uint8_t _thisAddress;\n\n /// Whether the transport is in promiscuous mode\n bool _promiscuous;\n\n /// TO header in the last received mesasge\n volatile uint8_t _rxHeaderTo;\n\n /// FROM header in the last received mesasge\n volatile uint8_t _rxHeaderFrom;\n\n /// ID header in the last received mesasge\n volatile uint8_t _rxHeaderId;\n\n /// FLAGS header in the last received mesasge\n volatile uint8_t _rxHeaderFlags;\n\n /// TO header to send in all messages\n uint8_t _txHeaderTo;\n\n /// FROM header to send in all messages\n uint8_t _txHeaderFrom;\n\n /// ID header to send in all messages\n uint8_t _txHeaderId;\n\n /// FLAGS header to send in all messages\n uint8_t _txHeaderFlags;\n\n /// The value of the last received RSSI value, in some transport specific units\n volatile int8_t _lastRssi;\n\n /// Count of the number of bad messages (eg bad checksum etc) received\n volatile uint16_t _rxBad;\n\n /// Count of the number of successfully transmitted messaged\n volatile uint16_t _rxGood;\n\n /// Count of the number of bad messages (correct checksum etc) received\n volatile uint16_t _txGood;\n\n private:\n\n};\n\n\n#endif\n" }, { "name": "src/RHUartDriver.cpp", "url": "src/RHUartDriver.cpp", "fileData": "#include \"RHUartDriver.h\"\n\ntemplate \nRHUartDriver::RHUartDriver(T& ss)\n :\n _ss(ss) {\n}\n\ntemplate \nbool RHUartDriver::init() {\n _ss.begin(57600);\n // _ss.listen();\n\n return true;\n}\n\ntemplate \nuint8_t RHUartDriver::uartAvailable(void) {\n return _ss.available();\n}\n\ntemplate \nuint8_t RHUartDriver::uartRead(void) {\n return _ss.read();\n}\n\ntemplate \nvoid RHUartDriver::uartTx(uint8_t reg, uint8_t* src, uint8_t len) {\n _ss.write('W');\n _ss.write(reg);\n _ss.write(len);\n for (int i = 0; i < len; i ++) {\n _ss.write(*(src + i));\n }\n}\n\ntemplate \nvoid RHUartDriver::uartRx(uint8_t reg, uint8_t* dest, uint8_t len) {\n _ss.write('R');\n _ss.write(reg);\n _ss.write(len);\n\n unsigned long timerStart, timerEnd;\n int i = 0;\n timerStart = millis();\n while (1) {\n if (_ss.available()) {\n *(dest + i) = _ss.read();\n i ++;\n if (i >= len) {\n break;\n }\n }\n\n timerEnd = millis();\n if (timerEnd - timerStart > 1000 * DEFAULT_TIMEOUT) {\n break;\n }\n }\n}\n\ntemplate \nuint8_t RHUartDriver::read(uint8_t reg) {\n uint8_t val = 0;\n uartRx(reg & ~RH_WRITE_MASK, &val, 1);\n return val;\n}\n\ntemplate \nvoid RHUartDriver::write(uint8_t reg, uint8_t val) {\n uartTx(reg | RH_WRITE_MASK, &val, 1);\n}\n\ntemplate \nvoid RHUartDriver::burstRead(uint8_t reg, uint8_t* dest, uint8_t len) {\n uartRx(reg & ~RH_WRITE_MASK, dest, len);\n}\n\ntemplate \nvoid RHUartDriver::burstWrite(uint8_t reg, uint8_t* src, uint8_t len) {\n uartTx(reg | RH_WRITE_MASK, src, len);\n}\n\n\n#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE\n template class RHUartDriver;\n#endif\ntemplate class RHUartDriver;\n\n#ifdef __AVR__\n #include \n template class RHUartDriver;\n#endif" }, { "name": "src/RHUartDriver.h", "url": "src/RHUartDriver.h", "fileData": "/*\n RHUartDriver.h\n A library for Grove - Lora 433MHz/470MHz RF or Grove - Lora 868MHz/915MHz RF\n\n Copyright (c) 2015 seeed technology inc.\n Website : www.seeed.cc\n Author : JY.W\n Modified Time: 2016-07-15\n\n The MIT License (MIT)\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in\n all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n THE SOFTWARE.\n*/\n\n#ifndef _RH_UART_Driver_H_\n#define _RH_UART_Driver_H_\n\n\n#include \n#include \"RHGenericDriver.h\"\n\n\n#define DEFAULT_TIMEOUT 3\n\n#define RH_WRITE_MASK 0x80\n\ntemplate\nclass RHUartDriver : public RHGenericDriver {\n public:\n\n RHUartDriver(T& ss);\n\n virtual bool init();\n\n uint8_t uartAvailable(void);\n\n uint8_t uartRead(void);\n\n // 'W' + 'Reg' + 'Len' + 'Data'\n void uartTx(uint8_t reg, uint8_t* src, uint8_t len);\n\n // 'R' + 'Reg' + 'Len'\n void uartRx(uint8_t reg, uint8_t* dest, uint8_t len);\n\n uint8_t read(uint8_t reg);\n\n void write(uint8_t reg, uint8_t val);\n\n void burstRead(uint8_t reg, uint8_t* dest, uint8_t len);\n\n void burstWrite(uint8_t reg, uint8_t* src, uint8_t len);\n\n protected:\n\n T& _ss;\n\n private:\n\n\n\n};\n\n#endif\n" }, { "name": "src/RH_RF95.cpp", "url": "src/RH_RF95.cpp", "fileData": "\n#include \"RH_RF95.h\"\n\n\n// These are indexed by the values of ModemConfigChoice\n// Stored in flash (program) memory to save SRAM\nPROGMEM static const ModemConfig MODEM_CONFIG_TABLE[] = {\n // 1d, 1e, 26\n { 0x72, 0x74, 0x00}, // Bw125Cr45Sf128 (the chip default)\n { 0x92, 0x74, 0x00}, // Bw500Cr45Sf128\n { 0x48, 0x94, 0x00}, // Bw31_25Cr48Sf512\n { 0x78, 0xc4, 0x00}, // Bw125Cr48Sf4096\n\n};\n\ntemplate \nRH_RF95::RH_RF95(T& ss)\n :\n RHUartDriver(ss),\n _rxBufValid(0) {\n}\n\ntemplate \nbool RH_RF95::init() {\n RHUartDriver::init();\n\n // Set sleep mode, so we can also set LORA mode:\n this->write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_SLEEP | RH_RF95_LONG_RANGE_MODE);\n delay(10); // Wait for sleep mode to take over from say, CAD\n\n // Check we are in sleep mode, with LORA set\n if (this->read(RH_RF95_REG_01_OP_MODE) != (RH_RF95_MODE_SLEEP | RH_RF95_LONG_RANGE_MODE)) {\n Serial.println(this->read(RH_RF95_REG_01_OP_MODE), HEX);\n return false; // No device present?\n }\n\n // Set up FIFO\n // We configure so that we can use the entire 256 byte FIFO for either receive\n // or transmit, but not both at the same time\n this->write(RH_RF95_REG_0E_FIFO_TX_BASE_ADDR, 0);\n this->write(RH_RF95_REG_0F_FIFO_RX_BASE_ADDR, 0);\n\n // Packet format is preamble + explicit-header + payload + crc\n // Explicit Header Mode\n // payload is TO + FROM + ID + FLAGS + message data\n // RX mode is implmented with RXCONTINUOUS\n // max message data length is 255 - 4 = 251 octets\n\n setModeIdle();\n\n // Set up default configuration\n // No Sync Words in LORA mode.\n setModemConfig(Bw125Cr45Sf128); // Radio default\n //setModemConfig(Bw125Cr48Sf4096); // slow and reliable?\n setPreambleLength(8); // Default is 8\n // An innocuous ISM frequency, same as RF22's\n //setFrequency(434.0);\n setFrequency(868.0);\n // Lowish power\n setTxPower(13);\n\n return true;\n}\n\n// C++ level interrupt handler for this instance\n// LORA is unusual in that it has several interrupt lines, and not a single, combined one.\n// On MiniWirelessLoRa, only one of the several interrupt lines (DI0) from the RFM95 is usefuly\n// connnected to the processor.\n// We use this to get RxDone and TxDone interrupts\n\ntemplate \nvoid RH_RF95::handleInterrupt() {\n // Read the interrupt register\n uint8_t irq_flags = this->read(RH_RF95_REG_12_IRQ_FLAGS);\n if (this->_mode == RHGenericDriver::RHModeRx && irq_flags & (RH_RF95_RX_TIMEOUT | RH_RF95_PAYLOAD_CRC_ERROR)) {\n this->_rxBad++;\n } else if (this->_mode == RHGenericDriver::RHModeRx && irq_flags & RH_RF95_RX_DONE) {\n // Have received a packet\n uint8_t len = this->read(RH_RF95_REG_13_RX_NB_BYTES);\n\n // Reset the fifo this->read ptr to the beginning of the packet\n this->write(RH_RF95_REG_0D_FIFO_ADDR_PTR, this->read(RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR));\n this->burstRead(RH_RF95_REG_00_FIFO, _buf, len);\n _bufLen = len;\n this->write(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags\n\n // Remember the RSSI of this packet\n // this is according to the doc, but is it really correct?\n // weakest receiveable signals are reported RSSI at about -66\n this->_lastRssi = this->read(RH_RF95_REG_1A_PKT_RSSI_VALUE) - 137;\n\n // We have received a message.\n validateRxBuf();\n if (_rxBufValid) {\n setModeIdle(); // Got one\n }\n } else if (this->_mode == RHGenericDriver::RHModeTx && irq_flags & RH_RF95_TX_DONE) {\n this->_txGood++;\n setModeIdle();\n }\n\n this->write(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags\n}\n\n// Check whether the latest received message is complete and uncorrupted\n\ntemplate \nvoid RH_RF95::validateRxBuf() {\n if (_bufLen < 4) {\n return; // Too short to be a real message\n }\n\n // Extract the 4 headers\n this->_rxHeaderTo = _buf[0];\n this->_rxHeaderFrom = _buf[1];\n this->_rxHeaderId = _buf[2];\n this->_rxHeaderFlags = _buf[3];\n\n if (this->_promiscuous || this->_rxHeaderTo == this->_thisAddress || this->_rxHeaderTo == RH_BROADCAST_ADDRESS) {\n this->_rxGood++;\n _rxBufValid = true;\n }\n}\n\n\ntemplate \nbool RH_RF95::available() {\n if (this->uartAvailable()) {\n if (this->uartRead() == 'I') {\n handleInterrupt();\n }\n }\n\n if (this->_mode == RHGenericDriver::RHModeTx) {\n return false;\n }\n setModeRx();\n\n return _rxBufValid; // Will be set by the interrupt handler when a good message is received\n}\n\ntemplate \nvoid RH_RF95::clearRxBuf() {\n _rxBufValid = false;\n _bufLen = 0;\n}\n\n\ntemplate \nbool RH_RF95::recv(uint8_t* buf, uint8_t* len) {\n if (!available()) {\n return false;\n }\n if (buf && len) {\n // Skip the 4 headers that are at the beginning of the rxBuf\n if (*len > _bufLen - RH_RF95_HEADER_LEN) {\n *len = _bufLen - RH_RF95_HEADER_LEN;\n }\n memcpy(buf, _buf + RH_RF95_HEADER_LEN, *len);\n }\n clearRxBuf(); // This message accepted and cleared\n return true;\n}\n\n\ntemplate \nbool RH_RF95::send(uint8_t* data, uint8_t len) {\n if (len > RH_RF95_MAX_MESSAGE_LEN) {\n return false;\n }\n\n this->waitPacketSent(); // Make sure we dont interrupt an outgoing message\n setModeIdle();\n\n // Position at the beginning of the FIFO\n this->write(RH_RF95_REG_0D_FIFO_ADDR_PTR, 0);\n\n // The headers\n this->write(RH_RF95_REG_00_FIFO, this->_txHeaderTo);\n this->write(RH_RF95_REG_00_FIFO, this->_txHeaderFrom);\n this->write(RH_RF95_REG_00_FIFO, this->_txHeaderId);\n this->write(RH_RF95_REG_00_FIFO, this->_txHeaderFlags);\n\n // The message data\n this->burstWrite(RH_RF95_REG_00_FIFO, data, len);\n this->write(RH_RF95_REG_22_PAYLOAD_LENGTH, len + RH_RF95_HEADER_LEN);\n\n setModeTx(); // Start the transmitter\n // when Tx is done, interruptHandler will fire and radio mode will return to STANDBY\n\n //this->write(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags\n return true;\n}\n\n\ntemplate \nbool RH_RF95::printRegisters() {\n #ifdef RH_HAVE_SERIAL\n uint8_t registers[] = { 0x01, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x014, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27};\n\n uint8_t i;\n for (i = 0; i < sizeof(registers); i++) {\n Serial.print(registers[i], HEX);\n Serial.print(\": \");\n Serial.println(this->read(registers[i]), HEX);\n }\n #endif\n return true;\n}\n\n\ntemplate \nuint8_t RH_RF95::maxMessageLength() {\n return RH_RF95_MAX_MESSAGE_LEN;\n}\n\n\ntemplate \nbool RH_RF95::setFrequency(float centre) {\n // Frf = FRF / FSTEP\n uint32_t frf = (centre * 1000000.0) / RH_RF95_FSTEP;\n this->write(RH_RF95_REG_06_FRF_MSB, (frf >> 16) & 0xff);\n this->write(RH_RF95_REG_07_FRF_MID, (frf >> 8) & 0xff);\n this->write(RH_RF95_REG_08_FRF_LSB, frf & 0xff);\n\n return true;\n}\n\n\ntemplate \nvoid RH_RF95::setModeIdle() {\n if (this->_mode != RHGenericDriver::RHModeIdle) {\n this->write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_STDBY);\n this->_mode = RHGenericDriver::RHModeIdle;\n }\n}\n\n\ntemplate \nbool RH_RF95::sleep() {\n if (this->_mode != RHGenericDriver::RHModeSleep) {\n this->write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_SLEEP);\n this->_mode = RHGenericDriver::RHModeSleep;\n }\n return true;\n}\n\n\ntemplate \nvoid RH_RF95::setModeRx() {\n if (this->_mode != RHGenericDriver::RHModeRx) {\n this->write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_RXCONTINUOUS);\n this->write(RH_RF95_REG_40_DIO_MAPPING1, 0x00); // Interrupt on RxDone\n this->_mode = RHGenericDriver::RHModeRx;\n }\n}\n\n\ntemplate \nvoid RH_RF95::setModeTx() {\n if (this->_mode != RHGenericDriver::RHModeTx) {\n this->write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_TX);\n this->write(RH_RF95_REG_40_DIO_MAPPING1, 0x40); // Interrupt on TxDone\n this->_mode = RHGenericDriver::RHModeTx;\n }\n}\n\n\ntemplate \nvoid RH_RF95::setTxPower(int8_t power, bool useRFO) {\n // Sigh, different behaviours depending on whther the module use PA_BOOST or the RFO pin\n // for the transmitter output\n if (useRFO) {\n if (power > 14) {\n power = 14;\n }\n if (power < -1) {\n power = -1;\n }\n this->write(RH_RF95_REG_09_PA_CONFIG, RH_RF95_MAX_POWER | (power + 1));\n } else {\n if (power > 23) {\n power = 23;\n }\n if (power < 5) {\n power = 5;\n }\n\n // For RH_RF95_PA_DAC_ENABLE, manual says '+20dBm on PA_BOOST when OutputPower=0xf'\n // RH_RF95_PA_DAC_ENABLE actually adds about 3dBm to all power levels. We will us it\n // for 21 and 23dBm\n if (power > 20) {\n this->write(RH_RF95_REG_4D_PA_DAC, RH_RF95_PA_DAC_ENABLE);\n power -= 3;\n } else {\n this->write(RH_RF95_REG_4D_PA_DAC, RH_RF95_PA_DAC_DISABLE);\n }\n\n // RFM95/96/97/98 does not have RFO pins connected to anything. Only PA_BOOST\n // pin is connected, so must use PA_BOOST\n // Pout = 2 + OutputPower.\n // The documentation is pretty confusing on this topic: PaSelect says the max power is 20dBm,\n // but OutputPower claims it would be 17dBm.\n // My measurements show 20dBm is correct\n this->write(RH_RF95_REG_09_PA_CONFIG, RH_RF95_PA_SELECT | (power - 5));\n }\n}\n\n// Sets registers from a canned modem configuration structure\ntemplate \nvoid RH_RF95::setModemRegisters(const ModemConfig* config) {\n this->write(RH_RF95_REG_1D_MODEM_CONFIG1, config->reg_1d);\n this->write(RH_RF95_REG_1E_MODEM_CONFIG2, config->reg_1e);\n this->write(RH_RF95_REG_26_MODEM_CONFIG3, config->reg_26);\n}\n\n// Set one of the canned FSK Modem configs\n// Returns true if its a valid choice\ntemplate \nbool RH_RF95::setModemConfig(ModemConfigChoice index) {\n if (index > (signed int)(sizeof(MODEM_CONFIG_TABLE) / sizeof(ModemConfig))) {\n return false;\n }\n\n ModemConfig cfg;\n memcpy_P(&cfg, &MODEM_CONFIG_TABLE[index], sizeof(ModemConfig));\n setModemRegisters(&cfg);\n\n return true;\n}\n\ntemplate \nvoid RH_RF95::setPreambleLength(uint16_t bytes) {\n this->write(RH_RF95_REG_20_PREAMBLE_MSB, bytes >> 8);\n this->write(RH_RF95_REG_21_PREAMBLE_LSB, bytes & 0xff);\n}\n\n#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE\n template class RH_RF95;\n#endif\ntemplate class RH_RF95;\n\n#ifdef __AVR__\n #include \n template class RH_RF95;\n#endif" }, { "name": "src/RH_RF95.h", "url": "src/RH_RF95.h", "fileData": "\n\n#ifndef RH_RF95_h\n#define RH_RF95_h\n\n\n#include \"RHUartDriver.h\"\n\n\n#define RH_HAVE_SERIAL\n\n// Max number of octets the LORA Rx/Tx FIFO can hold\n#define RH_RF95_FIFO_SIZE 255\n\n// This is the maximum number of bytes that can be carried by the LORA.\n// We use some for headers, keeping fewer for RadioHead messages\n#define RH_RF95_MAX_PAYLOAD_LEN RH_RF95_FIFO_SIZE\n\n// The length of the headers we add.\n// The headers are inside the LORA's payload\n#define RH_RF95_HEADER_LEN 4\n\n// This is the maximum message length that can be supported by this driver.\n// Can be pre-defined to a smaller size (to save SRAM) prior to including this header\n// Here we allow for 1 byte message length, 4 bytes headers, user data and 2 bytes of FCS\n#ifndef RH_RF95_MAX_MESSAGE_LEN\n #define RH_RF95_MAX_MESSAGE_LEN (RH_RF95_MAX_PAYLOAD_LEN - RH_RF95_HEADER_LEN)\n#endif\n\n// The crystal oscillator frequency of the module\n#define RH_RF95_FXOSC 32000000.0\n\n// The Frequency Synthesizer step = RH_RF95_FXOSC / 2^^19\n#define RH_RF95_FSTEP (RH_RF95_FXOSC / 524288)\n\n\n// Register names (LoRa Mode, from table 85)\n#define RH_RF95_REG_00_FIFO 0x00\n#define RH_RF95_REG_01_OP_MODE 0x01\n#define RH_RF95_REG_02_RESERVED 0x02\n#define RH_RF95_REG_03_RESERVED 0x03\n#define RH_RF95_REG_04_RESERVED 0x04\n#define RH_RF95_REG_05_RESERVED 0x05\n#define RH_RF95_REG_06_FRF_MSB 0x06\n#define RH_RF95_REG_07_FRF_MID 0x07\n#define RH_RF95_REG_08_FRF_LSB 0x08\n#define RH_RF95_REG_09_PA_CONFIG 0x09\n#define RH_RF95_REG_0A_PA_RAMP 0x0a\n#define RH_RF95_REG_0B_OCP 0x0b\n#define RH_RF95_REG_0C_LNA 0x0c\n#define RH_RF95_REG_0D_FIFO_ADDR_PTR 0x0d\n#define RH_RF95_REG_0E_FIFO_TX_BASE_ADDR 0x0e\n#define RH_RF95_REG_0F_FIFO_RX_BASE_ADDR 0x0f\n#define RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR 0x10\n#define RH_RF95_REG_11_IRQ_FLAGS_MASK 0x11\n#define RH_RF95_REG_12_IRQ_FLAGS 0x12\n#define RH_RF95_REG_13_RX_NB_BYTES 0x13\n#define RH_RF95_REG_14_RX_HEADER_CNT_VALUE_MSB 0x14\n#define RH_RF95_REG_15_RX_HEADER_CNT_VALUE_LSB 0x15\n#define RH_RF95_REG_16_RX_PACKET_CNT_VALUE_MSB 0x16\n#define RH_RF95_REG_17_RX_PACKET_CNT_VALUE_LSB 0x17\n#define RH_RF95_REG_18_MODEM_STAT 0x18\n#define RH_RF95_REG_19_PKT_SNR_VALUE 0x19\n#define RH_RF95_REG_1A_PKT_RSSI_VALUE 0x1a\n#define RH_RF95_REG_1B_RSSI_VALUE 0x1b\n#define RH_RF95_REG_1C_HOP_CHANNEL 0x1c\n#define RH_RF95_REG_1D_MODEM_CONFIG1 0x1d\n#define RH_RF95_REG_1E_MODEM_CONFIG2 0x1e\n#define RH_RF95_REG_1F_SYMB_TIMEOUT_LSB 0x1f\n#define RH_RF95_REG_20_PREAMBLE_MSB 0x20\n#define RH_RF95_REG_21_PREAMBLE_LSB 0x21\n#define RH_RF95_REG_22_PAYLOAD_LENGTH 0x22\n#define RH_RF95_REG_23_MAX_PAYLOAD_LENGTH 0x23\n#define RH_RF95_REG_24_HOP_PERIOD 0x24\n#define RH_RF95_REG_25_FIFO_RX_BYTE_ADDR 0x25\n#define RH_RF95_REG_26_MODEM_CONFIG3 0x26\n\n#define RH_RF95_REG_40_DIO_MAPPING1 0x40\n#define RH_RF95_REG_41_DIO_MAPPING2 0x41\n#define RH_RF95_REG_42_VERSION 0x42\n\n#define RH_RF95_REG_4B_TCXO 0x4b\n#define RH_RF95_REG_4D_PA_DAC 0x4d\n#define RH_RF95_REG_5B_FORMER_TEMP 0x5b\n#define RH_RF95_REG_61_AGC_REF 0x61\n#define RH_RF95_REG_62_AGC_THRESH1 0x62\n#define RH_RF95_REG_63_AGC_THRESH2 0x63\n#define RH_RF95_REG_64_AGC_THRESH3 0x64\n\n// RH_RF95_REG_01_OP_MODE 0x01\n#define RH_RF95_LONG_RANGE_MODE 0x80\n#define RH_RF95_ACCESS_SHARED_REG 0x40\n#define RH_RF95_MODE 0x07\n#define RH_RF95_MODE_SLEEP 0x00\n#define RH_RF95_MODE_STDBY 0x01\n#define RH_RF95_MODE_FSTX 0x02\n#define RH_RF95_MODE_TX 0x03\n#define RH_RF95_MODE_FSRX 0x04\n#define RH_RF95_MODE_RXCONTINUOUS 0x05\n#define RH_RF95_MODE_RXSINGLE 0x06\n#define RH_RF95_MODE_CAD 0x07\n\n// RH_RF95_REG_09_PA_CONFIG 0x09\n#define RH_RF95_PA_SELECT 0x80\n#define RH_RF95_MAX_POWER 0x70\n#define RH_RF95_OUTPUT_POWER 0x0f\n\n// RH_RF95_REG_0A_PA_RAMP 0x0a\n#define RH_RF95_LOW_PN_TX_PLL_OFF 0x10\n#define RH_RF95_PA_RAMP 0x0f\n#define RH_RF95_PA_RAMP_3_4MS 0x00\n#define RH_RF95_PA_RAMP_2MS 0x01\n#define RH_RF95_PA_RAMP_1MS 0x02\n#define RH_RF95_PA_RAMP_500US 0x03\n#define RH_RF95_PA_RAMP_250US 0x0\n#define RH_RF95_PA_RAMP_125US 0x05\n#define RH_RF95_PA_RAMP_100US 0x06\n#define RH_RF95_PA_RAMP_62US 0x07\n#define RH_RF95_PA_RAMP_50US 0x08\n#define RH_RF95_PA_RAMP_40US 0x09\n#define RH_RF95_PA_RAMP_31US 0x0a\n#define RH_RF95_PA_RAMP_25US 0x0b\n#define RH_RF95_PA_RAMP_20US 0x0c\n#define RH_RF95_PA_RAMP_15US 0x0d\n#define RH_RF95_PA_RAMP_12US 0x0e\n#define RH_RF95_PA_RAMP_10US 0x0f\n\n// RH_RF95_REG_0B_OCP 0x0b\n#define RH_RF95_OCP_ON 0x20\n#define RH_RF95_OCP_TRIM 0x1f\n\n// RH_RF95_REG_0C_LNA 0x0c\n#define RH_RF95_LNA_GAIN 0xe0\n#define RH_RF95_LNA_BOOST 0x03\n#define RH_RF95_LNA_BOOST_DEFAULT 0x00\n#define RH_RF95_LNA_BOOST_150PC 0x11\n\n// RH_RF95_REG_11_IRQ_FLAGS_MASK 0x11\n#define RH_RF95_RX_TIMEOUT_MASK 0x80\n#define RH_RF95_RX_DONE_MASK 0x40\n#define RH_RF95_PAYLOAD_CRC_ERROR_MASK 0x20\n#define RH_RF95_VALID_HEADER_MASK 0x10\n#define RH_RF95_TX_DONE_MASK 0x08\n#define RH_RF95_CAD_DONE_MASK 0x04\n#define RH_RF95_FHSS_CHANGE_CHANNEL_MASK 0x02\n#define RH_RF95_CAD_DETECTED_MASK 0x01\n\n// RH_RF95_REG_12_IRQ_FLAGS 0x12\n#define RH_RF95_RX_TIMEOUT 0x80\n#define RH_RF95_RX_DONE 0x40\n#define RH_RF95_PAYLOAD_CRC_ERROR 0x20\n#define RH_RF95_VALID_HEADER 0x10\n#define RH_RF95_TX_DONE 0x08\n#define RH_RF95_CAD_DONE 0x04\n#define RH_RF95_FHSS_CHANGE_CHANNEL 0x02\n#define RH_RF95_CAD_DETECTED 0x01\n\n// RH_RF95_REG_18_MODEM_STAT 0x18\n#define RH_RF95_RX_CODING_RATE 0xe0\n#define RH_RF95_MODEM_STATUS_CLEAR 0x10\n#define RH_RF95_MODEM_STATUS_HEADER_INFO_VALID 0x08\n#define RH_RF95_MODEM_STATUS_RX_ONGOING 0x04\n#define RH_RF95_MODEM_STATUS_SIGNAL_SYNCHRONIZED 0x02\n#define RH_RF95_MODEM_STATUS_SIGNAL_DETECTED 0x01\n\n// RH_RF95_REG_1C_HOP_CHANNEL 0x1c\n#define RH_RF95_PLL_TIMEOUT 0x80\n#define RH_RF95_RX_PAYLOAD_CRC_IS_ON 0x40\n#define RH_RF95_FHSS_PRESENT_CHANNEL 0x3f\n\n// RH_RF95_REG_1D_MODEM_CONFIG1 0x1d\n#define RH_RF95_BW 0xc0\n#define RH_RF95_BW_125KHZ 0x00\n#define RH_RF95_BW_250KHZ 0x40\n#define RH_RF95_BW_500KHZ 0x80\n#define RH_RF95_BW_RESERVED 0xc0\n#define RH_RF95_CODING_RATE 0x38\n#define RH_RF95_CODING_RATE_4_5 0x00\n#define RH_RF95_CODING_RATE_4_6 0x08\n#define RH_RF95_CODING_RATE_4_7 0x10\n#define RH_RF95_CODING_RATE_4_8 0x18\n#define RH_RF95_IMPLICIT_HEADER_MODE_ON 0x04\n#define RH_RF95_RX_PAYLOAD_CRC_ON 0x02\n#define RH_RF95_LOW_DATA_RATE_OPTIMIZE 0x01\n\n// RH_RF95_REG_1E_MODEM_CONFIG2 0x1e\n#define RH_RF95_SPREADING_FACTOR 0xf0\n#define RH_RF95_SPREADING_FACTOR_64CPS 0x60\n#define RH_RF95_SPREADING_FACTOR_128CPS 0x70\n#define RH_RF95_SPREADING_FACTOR_256CPS 0x80\n#define RH_RF95_SPREADING_FACTOR_512CPS 0x90\n#define RH_RF95_SPREADING_FACTOR_1024CPS 0xa0\n#define RH_RF95_SPREADING_FACTOR_2048CPS 0xb0\n#define RH_RF95_SPREADING_FACTOR_4096CPS 0xc0\n#define RH_RF95_TX_CONTINUOUS_MOE 0x08\n#define RH_RF95_AGC_AUTO_ON 0x04\n#define RH_RF95_SYM_TIMEOUT_MSB 0x03\n\n// RH_RF95_REG_4D_PA_DAC 0x4d\n#define RH_RF95_PA_DAC_DISABLE 0x04\n#define RH_RF95_PA_DAC_ENABLE 0x07\n\n/// Defines register values for a set of modem configuration registers\n/// that can be passed to setModemRegisters() if none of the choices in\n/// ModemConfigChoice suit your need setModemRegisters() writes the\n/// register values from this structure to the appropriate registers\n/// to set the desired spreading factor, coding rate and bandwidth\ntypedef struct {\n uint8_t reg_1d; ///< Value for register RH_RF95_REG_1D_MODEM_CONFIG1\n uint8_t reg_1e; ///< Value for register RH_RF95_REG_1E_MODEM_CONFIG2\n uint8_t reg_26; ///< Value for register RH_RF95_REG_26_MODEM_CONFIG3\n} ModemConfig;\n\ntemplate\nclass RH_RF95 : public RHUartDriver {\n public:\n\n\n /// Choices for setModemConfig() for a selected subset of common\n /// data rates. If you need another configuration,\n /// determine the necessary settings and call setModemRegisters() with your\n /// desired settings. It might be helpful to use the LoRa calculator mentioned in\n /// http://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf\n /// These are indexes into MODEM_CONFIG_TABLE. We strongly recommend you use these symbolic\n /// definitions and not their integer equivalents: its possible that new values will be\n /// introduced in later versions (though we will try to avoid it).\n typedef enum {\n Bw125Cr45Sf128 = 0,\t ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range\n Bw500Cr45Sf128,\t ///< Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range\n Bw31_25Cr48Sf512,\t ///< Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range\n Bw125Cr48Sf4096, ///< Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. Slow+long range\n } ModemConfigChoice;\n\n RH_RF95(T& ss);\n\n /// Initialise the Driver transport hardware and software.\n /// Make sure the Driver is properly configured before calling init().\n /// \\return true if initialisation succeeded.\n virtual bool init();\n\n /// Prints the value of all chip registers\n /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform\n /// For debugging purposes only.\n /// \\return true on success\n bool printRegisters();\n\n /// Sets all the registered required to configure the data modem in the RF95/96/97/98, including the bandwidth,\n /// spreading factor etc. You can use this to configure the modem with custom configurations if none of the\n /// canned configurations in ModemConfigChoice suit you.\n /// \\param[in] config A ModemConfig structure containing values for the modem configuration registers.\n void setModemRegisters(const ModemConfig* config);\n\n /// Select one of the predefined modem configurations. If you need a modem configuration not provided\n /// here, use setModemRegisters() with your own ModemConfig.\n /// \\param[in] index The configuration choice.\n /// \\return true if index is a valid choice.\n bool setModemConfig(ModemConfigChoice index);\n\n /// Tests whether a new message is available\n /// from the Driver.\n /// On most drivers, this will also put the Driver into RHModeRx mode until\n /// a message is actually received by the transport, when it wil be returned to RHModeIdle.\n /// This can be called multiple times in a timeout loop\n /// \\return true if a new, complete, error-free uncollected message is available to be retreived by recv()\n virtual bool available();\n\n /// Turns the receiver on if it not already on.\n /// If there is a valid message available, copy it to buf and return true\n /// else return false.\n /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).\n /// You should be sure to call this function frequently enough to not miss any messages\n /// It is recommended that you call it in your main loop.\n /// \\param[in] buf Location to copy the received message\n /// \\param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.\n /// \\return true if a valid message was copied to buf\n virtual bool recv(uint8_t* buf, uint8_t* len);\n\n /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().\n /// Then loads a message into the transmitter and starts the transmitter. Note that a message length\n /// of 0 is permitted.\n /// \\param[in] data Array of data to be sent\n /// \\param[in] len Number of bytes of data to send\n /// \\return true if the message length was valid and it was correctly queued for transmit\n virtual bool send(uint8_t* data, uint8_t len);\n\n /// Sets the length of the preamble\n /// in bytes.\n /// Caution: this should be set to the same\n /// value on all nodes in your network. Default is 8.\n /// Sets the message preamble length in RH_RF95_REG_??_PREAMBLE_?SB\n /// \\param[in] bytes Preamble length in bytes.\n void setPreambleLength(uint16_t bytes);\n\n /// Returns the maximum message length\n /// available in this Driver.\n /// \\return The maximum legal message length\n virtual uint8_t maxMessageLength();\n\n /// Sets the transmitter and receiver\n /// centre frequency.\n /// \\param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution: RFM95/96/97/98 comes in several\n /// different frequency ranges, and setting a frequency outside that range of your radio will probably not work\n /// \\return true if the selected frquency centre is within range\n bool setFrequency(float centre);\n\n /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running,\n /// disables them.\n void setModeIdle();\n\n /// If current mode is Tx or Idle, changes it to Rx.\n /// Starts the receiver in the RF95/96/97/98.\n void setModeRx();\n\n /// If current mode is Rx or Idle, changes it to Rx. F\n /// Starts the transmitter in the RF95/96/97/98.\n void setModeTx();\n\n /// Sets the transmitter power output level, and configures the transmitter pin.\n /// Be a good neighbour and set the lowest power level you need.\n /// Some SX1276/77/78/79 and compatible modules (such as RFM95/96/97/98)\n /// use the PA_BOOST transmitter pin for high power output (and optionally the PA_DAC)\n /// while some (such as the Modtronix inAir4 and inAir9)\n /// use the RFO transmitter pin for lower power but higher efficiency.\n /// You must set the appropriate power level and useRFO argument for your module.\n /// Check with your module manufacturer which transmtter pin is used on your module\n /// to ensure you are setting useRFO correctly.\n /// Failure to do so will result in very low\n /// transmitter power output.\n /// Caution: legal power limits may apply in certain countries.\n /// After init(), the power will be set to 13dBm, with useRFO false (ie PA_BOOST enabled).\n /// \\param[in] power Transmitter power level in dBm. For RFM95/96/97/98 LORA with useRFO false,\n /// valid values are from +5 to +23.\n /// For Modtronix inAir4 and inAir9 with useRFO true (ie RFO pins in use),\n /// valid values are from -1 to 14.\n /// \\param[in] useRFO If true, enables the use of the RFO transmitter pins instead of\n /// the PA_BOOST pin (false). Choose the correct setting for your module.\n void setTxPower(int8_t power, bool useRFO = false);\n\n /// Sets the radio into low-power sleep mode.\n /// If successful, the transport will stay in sleep mode until woken by\n /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc)\n /// Caution: there is a time penalty as the radio takes a finite time to wake from sleep mode.\n /// \\return true if sleep mode was successfully entered.\n virtual bool sleep();\n\n\n\n protected:\n /// This is a low level function to handle the interrupts for one instance of RH_RF95.\n /// Called automatically by isr*()\n /// Should not need to be called by user code.\n void handleInterrupt();\n\n /// Examine the revceive buffer to determine whether the message is for this node\n void validateRxBuf();\n\n /// Clear our local receive buffer\n void clearRxBuf();\n\n private:\n /// Number of octets in the buffer\n volatile uint8_t _bufLen;\n\n /// The receiver/transmitter buffer\n uint8_t _buf[RH_RF95_MAX_PAYLOAD_LEN];\n\n /// True when there is a valid message in the buffer\n volatile bool _rxBufValid;\n};\n\n/// @example rf95_client.pde\n/// @example rf95_server.pde\n/// @example rf95_reliable_datagram_client.pde\n/// @example rf95_reliable_datagram_server.pde\n\n#endif\n\n" }, { "name": "src/simulator.h", "url": "src/simulator.h", "fileData": "// simulator.h\n// Lets Arduino RadioHead sketches run within a simulator on Linux as a single process\n// Copyright (C) 2014 Mike McCauley\n// $Id: simulator.h,v 1.4 2015/08/13 02:45:47 mikem Exp mikem $\n\n#ifndef simulator_h\n#define simulator_h\n\n#include \n#include \n#include \n#include \n\n// Equivalent types for common Arduino types like uint8_t are in stdint.h\n\n// Access to some globals\n// Command line args passed to the process.\nextern int _simulator_argc;\nextern char** _simulator_argv;\n\n// Definitions for various Arduino functions\nextern void delay(unsigned long ms);\nextern unsigned long millis();\nextern long random(long to);\nextern long random(long from, long to);\n\n// Equavalent to HardwareSerial in Arduino\n// but outputs to stdout\nclass SerialSimulator {\n public:\n#define DEC 10\n#define HEX 16\n#define OCT 8\n#define BIN 2\n\n // TODO: move these from being inlined\n void begin(int baud) {}\n\n size_t println(const char* s) {\n print(s);\n return printf(\"\\n\");\n }\n size_t print(const char* s) {\n return printf(\"%s\", s); // This style prevent warnings from [-Wformat-security]\n }\n size_t print(unsigned int n, int base = DEC) {\n if (base == DEC) {\n return printf(\"%d\", n);\n } else if (base == HEX) {\n return printf(\"%02x\", n);\n } else if (base == OCT) {\n return printf(\"%o\", n);\n }\n // TODO: BIN\n else {\n return 0;\n }\n }\n size_t print(char ch) {\n return printf(\"%c\", ch);\n }\n size_t println(char ch) {\n return printf(\"%c\\n\", ch);\n }\n size_t print(unsigned char ch, int base = DEC) {\n return print((unsigned int)ch, base);\n }\n size_t println(unsigned char ch, int base = DEC) {\n print((unsigned int)ch, base);\n return printf(\"\\n\");\n }\n\n};\n\n// Global instance of the Serial output\nextern SerialSimulator Serial;\n\n#endif\n" } ] } }, "platform": [ "mblockpc" ], "extApiVersion": [ "1.0.3" ], "name": "vdr grove Lora", "targets": [ "arduino_mega2560", "arduino_uno" ], "id": "18730", "sort": 999, "description": "", "homepage": "", "sourceFiles": "", "code": "// enter your javascript code here\n", "handler": "\nconst ExtHandler = {\n\n // when extension is loaded\n onLoad(app, target) {\n },\n\n // when extension is unloaded\n onUnload(app) {\n // TODO\n },\n\n // when device is connected\n onConnect(app, device) {\n // TODO\n },\n\n // when device is disconnected\n onDisconnect(app, device) {\n // TODO\n },\n\n // when stop button is clicked\n onStopAll(app, device) {\n // TODO\n },\n\n // before switch to upload mode\n beforeChangeUploadMode(app, device) {\n // TODO\n return true;\n },\n\n // before switch to debug mode\n beforeChangeDebugMode(app, device) {\n // TODO\n return true;\n },\n\n // after switched to upload mode\n afterChangeUploadMode(app, device) {\n // TODO\n return true;\n },\n\n // after switched to debug mode\n afterChangeDebugMode(app, device) {\n // TODO\n return true;\n },\n\n // when device is selected\n onSelect(app, device) {\n // TODO\n },\n\n // when device is unselected\n onUnselect(app, device) {\n // TODO\n },\n\n // before upload code\n beforeCodeUpload(app, device) {\n // TODO\n },\n\n // after code uploaded\n afterCodeUpload(app, device) {\n // TODO\n },\n\n // when receiving and reading byte\n onRead(app, device) {\n // TODO\n }\n}\n" }PK :~Tv;data.bak/categroy.json[ { "identify": "cate_25f02c8a", "name": "vdr grove Lora", "menuIconURI": "", "blockIcon": { "name": "Lora.png", "url": "https://mblock-expanded.oss-cn-shenzhen.aliyuncs.com/48687157c9ad4d6fa1243bebe8e94267.png" }, "colors": "#42CCFF", "eid": "18730", "id": "31830", "sort": 999, "create_time": 1634911077, "modify_time": 1653810197, "uid": 1281238 } ]PK :~Tx11data.bak/block.json[ { "eid": "18730", "cid": "31830", "name": "Initialiser Lora @[Dropdown](fieldMenu) @[Dropdown](fieldMenu) nombre de données @[Dropdown](fieldMenu) ", "opcode": "BLOCK_1653809874148", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": [ "\"src/RH_RF95.h\"" ], "lib": "", "declare": "SoftwareSerial LoraSerial(/*{pinDigit}*/, /*{pinDigit}*/ + 1);\r\nRH_RF95 rf95(LoraSerial);\r\n\r\nString rf95sData;\r\nconst int rf95nbData = /*{nbData}*/; \r\nfloat rf95fDatas[rf95nbData];\r\n\r\nvoid rf95resetFDatas(){\r\n for ( int i = 0 ; i < rf95nbData ; i++ ) {\r\n rf95fDatas[i]=0;\r\n }\r\n}\r\n", "setup": " while (!rf95.init()) {\r\n }\r\n rf95.setFrequency(/*{frequence}*/);", "code": "", "_loop": "" } }, "args": [ { "type": "fieldMenu", "name": "frequence", "menus": [ { "text": "433Mhz", "value": "433.0" }, { "text": "868Mhz", "value": "868.0" } ], "val": "433.0" }, { "type": "fieldMenu", "name": "pinDigit", "val": "2", "menus": [ { "text": "D2", "value": "2" }, { "text": "D3", "value": "3" }, { "text": "D4", "value": "4" }, { "text": "D5", "value": "5" }, { "text": "D6", "value": "6" }, { "text": "D7", "value": "7" }, { "text": "D8", "value": "8" } ] }, { "type": "fieldMenu", "name": "nbData", "val": "5", "menus": [ { "text": "5", "value": "5" }, { "text": "10", "value": "10" }, { "text": "15", "value": "15" }, { "text": "20", "value": "20" }, { "text": "texte", "value": "0" } ] } ], "id": "312032", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18730", "cid": "31830", "name": "Définir donnée n°@[Number](number) à @[Number](number) ", "opcode": "BLOCK_1653809874506", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "args": [ { "type": "number", "name": "index", "val": 1 }, { "type": "number", "name": "data", "val": 10 } ], "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "void rf95setFDatas(int i, float data){\r\n if ((i>=0) && (i {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "float rf95getFDatas(int i){\r\n if ((i>=0) && (i {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "rf95resetFDatas();", "_loop": "" } }, "id": "312035", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18730", "cid": "31830", "name": "Envoyer données", "opcode": "BLOCK_1653809875483", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "void rf95sendFDatas (){\r\n rf95.send((byte*)&rf95fDatas, sizeof(rf95fDatas));\r\n rf95.waitPacketSent();\r\n rf95resetFDatas();\r\n}", "setup": "", "code": "rf95sendFDatas();", "_loop": "" } }, "id": "312036", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18730", "cid": "31830", "name": "Reception de données", "opcode": "BLOCK_1653809875786", "blockType": "boolean", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "boolean rf95waitForFDatas(){\r\n if (rf95.available()) {\r\n rf95resetFDatas();\r\n uint8_t buflen = sizeof rf95fDatas;\r\n if (rf95.recv((byte*)rf95fDatas, &buflen)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}", "setup": "", "code": "rf95waitForFDatas()", "_loop": "" } }, "id": "312037", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18730", "cid": "31830", "name": "Lire text", "opcode": "BLOCK_1653809876062", "blockType": "string", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "rf95sData", "_loop": "" } }, "id": "312038", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18730", "cid": "31830", "name": "Envoyer text @[String](string) ", "opcode": "BLOCK_1653809876310", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "void rf95sendSData (String data){\r\n uint8_t buflen = data.length()+1;\r\n char dataArray[buflen];\r\n data.toCharArray(dataArray, buflen);\r\n rf95.send((byte*)&dataArray, sizeof(dataArray));\r\n rf95.waitPacketSent();\r\n rf95sData=\"\";\r\n}\r\n", "setup": "", "code": "rf95sendSData(/*{data}*/);", "_loop": "" } }, "args": [ { "type": "string", "name": "data", "val": "", "checkNumber": false } ], "id": "312039", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18730", "cid": "31830", "name": "Texte reçu", "opcode": "BLOCK_1653809876594", "blockType": "boolean", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "bool rf95waitForSData(){\r\n // Now wait for a reply\r\n rf95sData=\"\";\r\n uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];\r\n uint8_t len = sizeof(buf);\r\n\r\n if (rf95.available()) {\r\n // Should be a reply message for us now\r\n if (rf95.recv(buf, &len)) {\r\n buf[len] = '\\0';\r\n char* chReceived = (char*)buf;\r\n rf95sData = String(chReceived);\r\n return true;\r\n } \r\n }\r\n return false;\r\n}", "setup": "", "code": "rf95waitForSData()", "_loop": "" } }, "id": "312040", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 } ]PK :~T)L data.bak/translate.json[]PK :~T)L data.bak/facepanel.json[]PK :~Timgs/PK :~T] ] )imgs/48687157c9ad4d6fa1243bebe8e94267.pngPNG  IHDRddpTiCCPICC profile(}=H@_JEv(":Y(U,Vh/hҐ8 ?.κ: "ƃ~{ SM$j5#ܪ! Qz"w~ѯMxD95 fMOd%I!>'0ď\~\YA#'. x8 Y[J_k+iAKH 2("jH~?lU#P!~?ݭYr1Ų>.jXeN3pu&0Izm⺣{z%C%/MPr-зoC`H.3~rʙ߱bKGD pHYs.#.#x?vtIME8/}tEXtCommentCreated with GIMPW 4IDATx{UU? p!b%.>0QLf$Z֤)L9(iFS1s21j6\y:>sHYߙ3{ J tz`-̶{cQAn/O 3SXG3%5HڮmIH:B.Έ$%i*W$M-O2b40ESr2` ]\ N)t3lξ":KC,^/7&Jke$t)}tN/$:fpHe$$6Ic}@RN-$uv+h?`>p-Ly~O`_I@[U{-)tz?wQ0e. 4)^7%sJeT9I$!i. {IG*Ih,UcX#sqltqU t_ L3Og.&It%ҫt%m-,0q%]J\4I!EJdIvM^h<`f3<hlkw.nf]Z~[u4I 6C˸zꀯGÁ7jUEqA3[";mV&<2-bR,̍tJr-IRxYLJ}] ϻ.;FH/wGc}+$]df|.4,in1t tNWH>v~ZCr.~~ѣ*͏̬^j#fvKuz'e'pΧZD)!nů%ʓ,^*cVfQ 8S%Y{Ho<:t6T]d5*Û.3ٛB"#]gI{gvIOJ:]R2DRWZLK: nӦ%m0Z]SewZ ̒*e;u>7[#;t.)fȨ{9`E]_a9pOd 1AЊ,i^M4QC*%$UbfqL{m4(SJj_Q\p{ p5\_&Jvr-cK|ޒNJ+Q̩n%af̵A 57bL7%JzVlHA _8yvXCIR_m-OJcRl[8tu VuZ df15mb{ wߤa[`f2:.DZ.uFUXOݗv,Ȕ_0fIˁ8XJ[oy$p)p<>,Ζ뻔>Mх(ga+pvp1) ڹIwkf=>0]h_+&E=\뺯XUho;qq_KzvUЏCҳf|(´e8gUL& Yb%ۻn(7{qRmta:x>`I7wZ+bYsEk]Nҷ|H?U!{HZ1Y%W|bᶘviV }S+q9zѾ4xiJuS:,E&J;"=|bgUap6d]WߞAta$*U7&g ,0̾aCg9R~g||_C 38|_ DU'-[3Cfpd5nٜN4h2jNh^#oP`Z6Ljkr!3ݤoJXB[sdÈ fϕ4ZҞ:&I鷄Q-cF:ZsJN㒾i? EZe_j uɝc}f2yB0Xջ]m,Ү/Pkf+)ΌǸ]>e$iamnR{%=U=Zi6(inDV6D[ MsD%D$6%E!up#OOհ1e o;I#ɒ&"'wZFItvjԈ,I]u%:/$ϛ8y$QyzcqK̬)Dfvξ2Jz1Ƒ{T҄%Y#8/Ώl!}$t%ujC?~4u~bf++cb׉{y(be [Dtӎ]L5AIǺʩg`IrcI|e9ÈJIgdU𰙽Y̶VOw3ەK[ r/M3 Ȝ6?;"zIENDB`PK :~T8s}})imgs/0c0b5eb22188494f9d7a2aa266c9e413.jpg ExifMM*bj(1"r2i ' 'Adobe Photoshop CC 2017 (Windows)2016:11:28 17:04:00 "*(2 HH Adobe_CMAdobed            x" ?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)EWXCAqKַ_s#4+kNV>@?9%=rIHIJI$RI$I%?TI%)$IJI$RI$I%)swԮڦ+EڗG.-7? M/͔T5{2>F?娒I$$I)I$JTI%)$IJI$RI$I%)EkX$y)$7vwX,~qޛ8e'{]o=Eر[5>df?<5 {/ȵmXYqrs-emzǮZz\Ʒ/}?Wl?\>d}X}bas2r~{}Wzr_cXih61p{Z7mrѳ13V&Vkji-]MBI$I%?TI%)$IJI$RI$I%)ǢpeU4Z7=橓Oe]>uΩۍ]ī:cdTQk?3FV{ t?u}rm]UE/ӿԛ(+g z5y83?Fʼm8]W.%{gu6Q_; f̃ca,5Ic7m. p,{Moc۲m^g$d@ oTd j=kqYqulc_kߵE$RI%)$IOTI%)$IJI%_32:uI8$-2u!78ޟXf3*!YEn0>1U,wW.jAg512 l^+#psiQ;ow*w%b[.seb k[}͹f&?*w5)*ZC\ȩ̊bYӮfϬe4ۆϴIl7G=X:}c"5g7ӭϣ?EF (`mU ٖ`Ug_j,eV&~ 2h~}T~Dz~;tzh eeZ v%3fC ov6q[Qc6&n\#uğY1lf36ʭk?KEc:Zm{E5cuXYvuskTeU̲co+=lz hvmY[*+ϵe~5f*=?.ؘ5ϩߛUc~_}aO.# ~-wVqt@&Wq~ _'^G]9yض߅],膶یַ8=>Z&g`lW?vkH@u@I$IRI$I$TI%)$IJI$S}q}WX:Su4eTN-̗73<Өe>:ds@.mowSѯtX#;].uAV[s6R'`Wx֩d.#bu.:[%O<YoO?1ٷ6zGpaso2XVƱ ckZk@RJy%3;0JkXִCZ4:I&/RI$I$$I)I$JTʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$Photoshop 3.08BIM%8BIM: printOutputPstSboolInteenumInteImg printSixteenBitbool printerNameTEXTprintProofSetupObjch!h7n proofSetupBltnenum builtinProof proofCMYK8BIM;-printOutputOptionsCptnboolClbrboolRgsMboolCrnCboolCntCboolLblsboolNgtvboolEmlDboolIntrboolBckgObjcRGBCRd doub@oGrn doub@oBl doub@oBrdTUntF#RltBld UntF#RltRsltUntF#Pxl@R vectorDataboolPgPsenumPgPsPgPCLeftUntF#RltTop UntF#RltScl UntF#Prc@YcropWhenPrintingboolcropRectBottomlong cropRectLeftlong cropRectRightlong cropRectToplong8BIMHH8BIM&?8BIM Z8BIM8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM08BIM-8BIM@@8BIM8BIM? g*h-1 nullboundsObjcRct1Top longLeftlongBtomlong RghtlongslicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlong RghtlongurlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM8BIM x  Adobe_CMAdobed            x" ?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)EWXCAqKַ_s#4+kNV>@?9%=rIHIJI$RI$I%?TI%)$IJI$RI$I%)swԮڦ+EڗG.-7? M/͔T5{2>F?娒I$$I)I$JTI%)$IJI$RI$I%)EkX$y)$7vwX,~qޛ8e'{]o=Eر[5>df?<5 {/ȵmXYqrs-emzǮZz\Ʒ/}?Wl?\>d}X}bas2r~{}Wzr_cXih61p{Z7mrѳ13V&Vkji-]MBI$I%?TI%)$IJI$RI$I%)ǢpeU4Z7=橓Oe]>uΩۍ]ī:cdTQk?3FV{ t?u}rm]UE/ӿԛ(+g z5y83?Fʼm8]W.%{gu6Q_; f̃ca,5Ic7m. p,{Moc۲m^g$d@ oTd j=kqYqulc_kߵE$RI%)$IOTI%)$IJI%_32:uI8$-2u!78ޟXf3*!YEn0>1U,wW.jAg512 l^+#psiQ;ow*w%b[.seb k[}͹f&?*w5)*ZC\ȩ̊bYӮfϬe4ۆϴIl7G=X:}c"5g7ӭϣ?EF (`mU ٖ`Ug_j,eV&~ 2h~}T~Dz~;tzh eeZ v%3fC ov6q[Qc6&n\#uğY1lf36ʭk?KEc:Zm{E5cuXYvuskTeU̲co+=lz hvmY[*+ϵe~5f*=?.ؘ5ϩߛUc~_}aO.# ~-wVqt@&Wq~ _'^G]9yض߅],膶یַ8=>Z&g`lW?vkH@u@I$IRI$I$TI%)$IJI$S}q}WX:Su4eTN-̗73<Өe>:ds@.mowSѯtX#;].uAV[s6R'`Wx֩d.#bu.:[%O<YoO?1ٷ6zGpaso2XVƱ ckZk@RJy%3;0JkXִCZ4:I&/RI$I$$I)I$JTʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!]Adobe PhotoshopAdobe Photoshop CC 20178BIM.http://ns.adobe.com/xap/1.0/ D7EA9DDDF2B19D75228EF80F3A23CE82 adobe:docid:photoshop:0ef520e0-b230-11e6-bbc5-955c1bcc9e32 adobe:docid:photoshop:5882d5b7-b547-11e6-ac66-fdfc08cbcd21 adobe:docid:photoshop:8eea8251-b22d-11e6-bbc5-955c1bcc9e32 adobe:docid:photoshop:dc13735d-b538-11e6-ac66-fdfc08cbcd21 xmp.did:5E4BEF7AD91BE611A42BF6F5E5F2EFEA xmp.did:644BEF7AD91BE611A42BF6F5E5F2EFEA xmp.did:DB0E728655AAE611A743989D6F6C7E0F Adobed@ X     u!"1A2# QBa$3Rqb%C&4r 5'S6DTsEF7Gc(UVWdte)8fu*9:HIJXYZghijvwxyzm!1"AQ2aqB#Rb3 $Cr4%ScD&5T6Ed' sFtUeuV7)(GWf8vgwHXhx9IYiy*:JZjz ?ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽tSw]}=wp$ە՘eI%mUj!%4N4햝|YP@HFmWh H |TZH5PP(hx\7#KO]PCWC]CW TRVQӼURA"r#2:0 AⲺTAA.CB##Ȏ{U׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^oI&|j\m̾.gPecޒl}T`G[[E4 Qi;jxrJO p賯{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^6J,٬6SQx243ʎVboLmm_X~Du;=]l`@Q\&g'N>H2EK눔 +z5qhO)_pm}Rl5)OۛW%po~o0{v[ϽWq:c?ugtY׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽ubgAӈjJh8)2)5>WhKV?FqDu$wή]噘7Tx]%D6pX[{]dk=}Cko@jJSE={ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u wQJj]{$k;~9*:dyP2u2l£:Z1K~Dlvht1TJͳ6:,kH/.- ?Lw,˟W(yOi:(׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uQ3FNܓH^s>˓PQmd{9}̀O6:[n56S0TOؘpg48]4 6w'JlԎO(׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u+kiOݿwO1cYv_cTe6Zeߪ'.~@u?tᇕGz_OKo1es6V<͒P~H``!gB{CwD={ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u+χ |M1RIMi#V'A"6"⭕K{ZZ!_=$f =i) vRU,ڭ$N~)LޅX`ŻWZڤuwW^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u*n߉7 { '*NԈ蘆mv'?hy~N4=iRP|X٩9 47gۋUBtqjICGD{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u*}P/ΰ ju/rC:_ob9E5'u_4?'72*!foL5Aڄ{O|?.r+ui ^8웠^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u*$?z"Uv԰}ԭ<<}vj(s?^58Z(|9ʦ [$U1k[U{)Ծ1& 6E׿:ޑCVxP-N~ɺu~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ_ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u?*幄*?*Qk6ėkd|?Cveܠqaܽ(xFُ}}q͓VDzN{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uF?].T}ۑ0ܽ{Sxm$5gd~8d 5T,!EbWXq 71c;SR^{(ꥆ 2rc6chG[V^&d5%\J+#.[dGΟt'PJi޷Nu{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~jU \?>ےwOmw67MYU4mp2lBXTe$ZbMZ>|d%N`W_` N8=+h]bwGP:]s1ogI TRJ,V0@MYO) i9㑔[5G"@8 ?_S'3~2 sm⏲E:jDnS6d &3x5᪨# ؔy tEYmv|8)!׺bܛl-n62#6G=2[TRD?I"wH䕂FOlM{s,>?/!MKC]% jv^?77HQ78ԁk@U@!X䁏Zq]|)S>;w)xλJl2Rߔ5 Ԧov; d`"G#r_˻dT;u NyD|J/8Մ{ P9~};&zDΩjiଢ$h)!CG4He$Ak+)*Gֺu{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~@ⱙ^G eي^[%-u}JIOWGYM+G,R+# Yp uOۃu|ۻjl؈+55K[O;Wuz2%Mj%> cC4[ӹӋ=i@1/mB$`>:uy <;dqhdFj)19u%Y^7FHDce. $Dj#"W]Tn"%Pү`IqGMMnB8fJd_$"z|mLϨO\Y5D?M p>u,ՎZ~U9K=MwSnny.έQakȭ8&Ŋ:d,)+?Xڤ".Rt W4Apx,܆b?N~Q7]߼;CwDo/>(lm[n >٘qav|{qKsaysM TQVPȊut.H$8,M(EYnH>pV?~`feotG׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^˓ó_+~syۥ'd]OTDe;TWnZii uJ=fn-)vZV#i%0z~z' 8OQS;nLvpx91< SFߺ*bxh#F=K$.\HEZIH\U#<`z!ē:d#lGmm*ld{b ѴlЬϾy%'bvdN*!RejX=QgC< &8AYINȁM(NHqpPFi>CLy:f\.'ӚTPisIXvIS<+IW@S8jq?z6yTi>|d֎)#z ͽU$n VRX<_Iw du/L?BtҾ@?*ލ|)wbe{#vkmik33X|y,cܰcq4@PU2^8,Α3Ni"Tw]>޻Ctb[k-11|mtXjf):uVMi.̲ +R*$/Z8߾s5qfՕ55-[[UY_[U]:va7r*"% *4r${E'7]Gh:ª凔jʼn&;wCm`XcýxǦiַso}S61 VsvnE^SzoV*ۂsSMTeIXouu Zc9 b=:߃CEv_3T5Դy䥩e;`eŶ9E[;%fZyTK큊-2L?L~dPyWw?Yml>덟vqc[Sgsob(]1cjJ HT~1s"F4?},9W,̚tU U-T2TDSS̍O VVYI[ՙX28:";_3l սU6;g E`6bKS 'ƶ"Ģd݂{/4[yرrid(fzwy $k,6SX;iSAgbj&=P:,7/Wir,FZߌ5HldQܙ 5Dm }l/KBdV2aP7mqfJy3/Mj)4=wp`-1#_7np{g[yVc`#i1X h-EnBh))`wuUrfb&yO~*z&U6[Pff|oG14ݵe$WV8sb >|KfSh&˫uP~GG__Ӂ 'plz8(3Hd3Ol)bCwL۹RI4Ēh:ٍTӯdwAW|+P6p9 /sVձ O<^5MN1BZ}b5>Un97.;I4xVSĤ4FhݎAִ4>x,% ? *Oͪާ5KZ W9mռkC2"}J֦y#A*zF 2]30@X|ItD]=x YZmy[Rq˛~MhJJWVY!~mJ?b u)qg09ޔTq5}Q %>LH 4),@D OK$R5-+P*ϧ[Gj >yye|R|f "DZGy!R].V-޻O#% jc\:|dqY-9Q9cHKTM)wwQ{h5-ƺup/mcL^(b޺1,R\TL"Vh!@a6ڏU2 yM~i2UyA?`|W*;_ԟ:zsqV%)ϒܹhNFÍjy*j&eZIeHԲݯm_Zdh{UEI#3W ftMW$*k+[!%J|썅V&wvJ`1S':v1ʛqbcRl$B$q,L7 15gjzbڢ;u )0+B||)LnCm{yN[W'G<Թ|MUcJ$z'I)#_BTߋZ[]FoM2q <k\,R( \y|"uf^+)gJd9LmEIaOIvF SB*Bͯ9i,79FRZts[[#ucy||{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺEgniϿp e ER; `x[;jcXWr ScC3OƷop@ ;qfdYi8Vd'fd4]a+pi۲q|5)O )OTdU"HaM{ i TdF\ p$Z&n@,~¿Uzou7JFڎ)Z4Myrj%,QeEy.z5imHp5?nW((ʇ4|.ힷ>ꌽ~۹(7fi0˰;]=6ޒ]n:zj A)}H"H}a+Z 䫺K 4<(~uUp*{"E*]K$;$[ȳ_\ hCAsfCTH :;!Gr_'kgt_uSNjE1he,p$/qIQ8.*3P={mQJl\j4Oاϭ~.|)jɴ6Z:`3R5v܂Mߔq) tz'f17DBKJE51Sҧt-|G=VFcE`3Sz4XV@ ,AI|뽋ru-7YNw~ eRbqܴxEQ1š :-V7q3qC1"nT*iu%?;ZPغۖ43I6B(um]0'qS2S΀tx5n D_νl:u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~bxiX১IgX,$qƊK1 .}UIrhI^ើXn?_'GwR|b謞chu2Bߖy{4/UݒcʼnB,4p)iknD3) ;PHjQhNє+:j .S),ax,n ܙ8^˭)/W%BXIP2yb ˸ti+" )@ #Ái<T}}+WKьٿ#://[{LSTT˶*E]QuZfe+,C}Ifm%u&3TaT G3ZÐ*=3_yl@N_\vlmi5$pdE:c/ SҖTA levj|Ǩ?n#_[p7fovv) c VDQqY\t49 \?o\nmzV4-˙vJ^ǚsj(q T֌mvw)PUOG_C) +h@,Jv{B [;AE?VC)KEJ_][QPTkwr6U|cI&IjjIMs1S>ξʷ-kz'*lv _fKI(v)Q4"W>މĭN*#WT(^'Dik >СA\j~`Tb[zj/׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~k Bɑ/;X;~Gx4_cM*k&GtpC<-5"GFgyk${`(%ȥr~\NՊSV4_I| ?Yt6&|^:+O 6pp"3fQ҈C+SUMU;8v; Q?/Eu>}jq4c?_O҃˪yvG{t 6OBm^)(Jw.RNNЕZiŵTX&ckԎ$aOky΋߻K2²;Y8&Q11Tç)RJi2SK #{4+I,X Pӣ|qI'<lPO'>RJ=({.<@@TS: F;i1<n=iUeQ3QS?:} itXqO}t#f{[t.A&]RmzzU@Ioa k7 <)PO^,FY,>_ g/u=W7Xm||-4Okr{ΘYcK0$70Mfܯ4|rcy0@GkC׎[ZM?m(ֺSo=︪t˒{'ZM]|,3Hk,dy'`owf7ܷkōM}I&z@"=E)_CԗfEuxr~1vn '?/4}"G"0 5n.KQaO4aeWXZ:tp+&ހN=/^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~|쿞\o?ܙ̊i״θl 3ҮCf4gTiX_h-v U5?=<1P+UG^jJ+P+QƤ~t^>g5\Oc0p: ?ce֣&*lʚcPE4OYU4bQQT9Q5Ŗڣ4XZT#Z$𠸸 B#vO.zu??(zko:MfI2M4$E,*e E4ʺ}ut.@!Ig|Ld\~ZZ_#4'hu&H У8dPl~%)p'?i?*_͏avfHջ$Ib"z}ɱ0NH3( PthV) |O,;j|1}q Sa}/ieZMwdbsz(pmZp:tb֪KsBC/f>ޝYlczTZ}?g[(/f{t}xX`2< h*+'ST ͬPIr%&~4UjňQPi6!gc(1BI^/=u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ_ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽tM/'?g05O[l拎$q'Ӹ؝3sjzƫo[>G#Ky+9@gs#9?iZWu1фV5zċA׍qy;Q-ۨ܆>7UOA0c3Gnf(:۝س9Wmޭ/-g&C~2Ơ 'p7}dhRW-L^vZm|{(]@+#Rh k&1Fl cT-*`;r\2]}RiĘ~>c[ρH9epE(Ġ11n~ zu{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺLrm9ۘ,tM=~c9(PIXi[07%;pUzjiUHT 鞱!:7ݥ#wq䒷T4-`e II Vr&TV~cFCH~Ek>Tx/m6HV!ڕo>swY2k)_hbk#-9;c0RdyeQ,I,"12Ϸ6l&-ـuQcLW7'Ż][6]T\$jr*GT['!ݱޒ:Z빱̭cD)q&T=CcP]xbH'c9ו㘯x63PjQcE3éO;bݦڦIU+­IПtLu*d |ۥmO-%&79ZmjTNe\n+>{%sL.W>'J`Ex)p\ֽd?{/"6#Hֺ|ljP r3:"]=N7=NTxY}^]UE>ΎD*LSX~\s]ȖR$Xe}{~43ې8ᦼ>|z_O>foQllWvxuyфSBd˾5x~-D1+jRv>QiVI5]%N]DVh&O)ӛF_xvn@K!G=6׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~QʿEe_]ײN6z}^5}3J`qnRtPӂtkeKb𐊈cs*XP9GQO1{oe$[]) TFT`a('{+YYo= %f'a`>*UH6"÷6qCa%C5fŝ/ղ#̀KV>B|GLe.ڝ c ~&?=Yms;}$,=69(Y,fqh;" ;IL#Ɔݭmd'HX:`hƪU!G<ɶ.Lk`doZwas!_-)43d:/Ye/pOΩ*(`@8uiۥ{{hn't퍓]ÅcomIV9nK;dYJb1%XÕGIZB}wHi$riӍ jh .|u{; NЛvư.Ԡg0YxʥD8L٩o$r"DRa, Q]^9=VnݤD7T49?=3mogi^ݛC~P%rӱ2yL>qϊz668SK7쌌}fqEM ex Z\[Cj ǭGϙC6Z[;&njcoe~G1PŚc39::m35 M/̵rNHL foO>|P"*j$v Lp.6|I ĥKôB Z׫Mя^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u#~ߺZ"v~۠۽EA[S[M*5UUJk)ved?x'Qu\m%|Xxx@'o+ŵ [&|ܛp휧Ul^РbVQ[+\m>ˬ8*22ѹ*̒R_wn6%χI+GuZP7˅nS-QX M_&8)G|)ۻ;q>ܿ{%2$0۠q`gf"j7%f/!T[4➚Y$x!DiH\nm9w lku11 U)eR d;y.D^`*T_rk@::5SܲuLV俽`)ܳW $邾݋A{FT;K" <*HyufpFU9}4iܸ݁:^Uoߧ=mwmb#v\핲E9L|P/!evovGnrl1*b4 3L2CI!8_SiktP5;v#Sԟ2z=9֓l>̓wP6ѭIܮoRAhHv]`9avOn;h'{SAHN'|upKnd^\}{>]|QSv.yy.+e{+1՘P>NQX91$ʶiq>JV@-F )zsMVԖ+_Aq=?;{:tPϝ]vmJ,Yo˃$qXEbOK0ewc[6p+]2ZRB,((E[6|\٘><%·t~#y_qPCUؔ8/)ԴK%\RVT{wp=FVR4in(Y"[w(-n*ڗLjOwfjM:-{_]Nf>m_ oɱWmv6^C_q[(Vc kv\-MuS7P2F*7[ɹDFw[yۃYE45Ђj jXZ jty%PideEp0VcText7~ceXW?2T,Kswio=8PfqYF1 Jֈ+H$ )GA4@#*D:rZ׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u"HTM!KgE$($܎$C9uVeAV`ϩ@V .#V~{ߺAWtw_[|~gv;S/<]tRDYeUFSIbÿ\y : PҌA=7|Z]YuFy-h MS\Xβ~IICCRap)7uWv}ˏ @JEb2&i؉(+U:_m|{h.x|,+z i =Sw==f].C/om݈#Tu;u,.jeZUHaQռ񑩕x]5>ZIF@ײiymjCi@1eji֫\vֽQPnѹ7\*NSrtOȮ fmOMYfO7PS ۘj|\oJޜۻr'r`pnŞ7 6Sq)!\^:L*I]d?!o|ek:CuK[) #}Q IV:49ndub~Fs%xd2Y PMw~jn-f|nپ;)[G7Q}6oS3ml: +[a(lmi?0BHd2U<+%Ǽa@Tx5qOpF&gUC&ǀ8BMSyTtl.72;vl{wR 6.3&'rdoc[[._I,PE&3ErY}:K7Ъ5ۻ~81CcqKN+RR9(E(‹GW&m0TZ(vf=B=ޡMyJiD((ǥn%7- 2|8w?wU⦒bHc}X H=ȳ~Xqt'=I_2+{s ໵j>QS wA47h||sUU;L2ÙirdU j1WKEa*m\?,dNQTFX8GQ$ϱ<̜͹lRL TVxv^mkW`);Kz(s\+!#ԒF$$lH A7Oi:,lThA(z+]pd5d2izU׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺAev[t׭ޝ6_re)I"FJ&Hϊ%"1َٴn{VROp|VUc̎]XB)1>'3|vPSb8ωFgdQUc1SĮ%23c,={SFRH?jm.y& DFDu/4yH+ڕtUׂ/o3 OQSֻkwhre$Nx%A喦*aa#Iv-vW+<Ͷ$^H|8ZJ?SZk~GyQ.]5$NŎT J~_>0?=՛o^ ?5]F[g1;ҿ R)wkf9(3.VZ:d0;#6s1ǯq=̏qQ[x4S-j*2:Dc#,uݵX_lohP0e@\J+Ϡ Ҳ6No7;VS ېvw3cWF ()ܿʞߴ7;6iyh Q1$bgn[1YXMYbJ/ߕ'fޝyG[bM>K 煪sݣ1sA6oCc-*ScמFo-l$sxej@/"UzRQmś驠4RQNWt]i:K}'`mf޹mFjUǗVa+1y8)imbO);](W%V?.mǘjppA%T?pYQOM oymuگ'K6#Ү@:ڤ&CVBhpb\'vn?Z4EpI)32fޢ5[ QQb&nK"$ʨc**JBΜeWvCikK $ 9yΪTu"s'-l[kuLݴ`U%I4ZJTi5] :el<.wBcO6G=ED23㱔.2U 餆T. ;9m,|+ȪrPԵ) S$L{{<;{+[Z\d<GWL46ُ$7/Ori}޹TA_ti]Ukai^=|ٔSTch%#P~OꣾruZTm%FmK8#IYoz,\-]6i)^:Y`!a$qpWJ9/~=f<딹. Xz51#{\˼Ɛ*S1qƀm/iدwr8rqASC'daM0C!8wk ۋ@A%#1Wϡ';E&mۊ2ޥYH]RHʿP/dzu{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽tqgH튝{l LL"Uy)ԤvVK AK1`I#ٞ׳nV2O6+ak*>}#ۡk딊ƟIOTMI$?{3>j/ش,Jڛ\IV-<%tFnSɲInIx/^'ф`FCǨq A,k_ͩ^zsߙose!GSSVV6:Z tL&tBcgi<6n<vtVw^{co$K.75G&x!̕&>g{y{.w";M$Y h(aI & 2aNls O$-^[iQB|)V`(7Z~l x]U)o .?'VS,ϒZ9*# (s̶Z ,\ D{p@Ao;9i, sS.)b B5+bխ ])C៲Шݵ]?=7v#1q٭dɿ7M[3OKKQQMF%Q~ꢪ;"sgqsw)=SKRS֊EJ%QAw޹p~d۶[R dRDļ.âk{n !3fRleJhnz-\8\^٢єLmD/rK$E\yr4H[t(g&ý q1+:xȩU2[*}z#ꝩ~n=ܛgŸb(joc7@)vC5EY\gAu*+XW4cBID>ZJGP`ڭ>qʬs.H7B@{za*+oc0XȎܛk-{vd])zz/'olql4͔ȅ.S;WzDAmfV"&妔T!wwej_j%p8 A+N}پ7ӇrI|w{˟59u[/l5IFc`IV!^ hHnVVGf? ޚ8R+ONs [?&a2C&q|KmqDV3-DS,NSK{r(X]lV VD5ZTSd7RU(MHuȡϗ YChZZW mT9>:L6J||Q)Qr0mϛ&'h-VέZxPp_ԁdTd" y<җvZTgQ$72-o*1򺖆IT6HRa)Si8+NVWX`yaRpLFF7K`xڷMi~]1.jRK^}S =,q. yTm|LGCU= 95b. 9.XGmIlj)^8iwmnV K\tb:;`|gH_;4:=h*oi;EњM+"Ԧ4R<8eo:չ->CVL43bUM:+]>B5S!ha! Lo\r\n8԰FbeC k)қ>N[hWR#Y-oC@|:ŗ]~{s)~3 adXY[QK@΢ą$9P۹mށhBU-unVw{m`]>,ttgfhpO4lUd+Hei-EHK2ẙlew͞mv:qa)Z pmO܊ !~#huIAGYd;#EvdMɃ|tL0q4TI+fh2B޸T*8Yͫamw xhw#:M0iPF 笤,7 rYv!R #)  zf;׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺAgnwwR6֟y[n%U TA$\by2z8gENH4ڶ]|]I;T7cEAbqǤw HcJOz?/j*m=6,3S'`̊EZ%RP4u91G~ݾø^> 1T7T)!F\_xr勰ֹQ?,O:Ha sWuWv_ll]L. mG_b蠬)q-$J\ܽ˷@.m,ẓÇR 9@ |ۧ8]߭lF"8c@XF:O{:5Xܣ7C}M;rO! &} []ϕXbザb^+esVVJ "qruŽ]TG%gi;lN;%QbE\ Y}8fUv3ko϶|3%處D-:U!/԰c~Kmn?JQȒBuD+(tL+C)[SWC:nm:Y}ﵳY܆绺.*=ۇ( .!B̒BȻ!%VS,- %I)2Qшa#fkۛo2$3-RteI@u+WPJtVRCuKy/~2e>:M۴#wI'}_#ٛx5l Uܨ)dx>F/4COʞrn;1J dQJ|ќUTr|-mvjR8.r (Lctի`&ͫ[W]ۛv~'5ӽ'yc&^a4Z*1>dTTDPw! b[Hfhi'Nأ7꺵K!7[CsuruNJ2FTP,=lޝgs _{mi}r[C9mki9 EQU6zFo+]I"QTeQ@T*&nLJަ `d АFŎAj-qׯ{l.w;_}YQijqؚ.R-Ǐ)xJ95e|}QzBB*&o۹)tmZhB~vV:s+Omv:P&04q,4pYޛ稳ɔ&WJ<'1V(vö0|M5D SYHF-R;feUERТwE,FLv^Kƾ9Vi&: ; U{7Fd1}px3rmIj5{kqg3T?1a+*i^8$PDj@8#$HJJ9ě$6ԖJdP4 JՒϑrzײsۿ OUX奧/Ŷ[3COAB3QfF:ٷau#hCO(K e @(Z2JlvﲬR“NA3%49 Rh:y* u]=E6۴yyR)`4*)>A1u*H+q\FGsR!%@sP)QJnn܉B+g?#'?]׏=٬-^m]mM:]{?dkk1yj ӻwkn˴Dk*M_0[^+$L򲢼Mko;HThV3YYɾf#$hŤwU*#*5nRB i$E5>AKg4𤟢Hp )!!֫]M#Py?Bt%thE}*< 1 &" V52(cCLUe,4ir>'"RVzī-E\[ OBSW*GQ$ᒤ5d2G$Lʂ@C.?.y/χI4b? ݳOvloqx_nG'pFRRCHM3J":Ywک-ӿ[E4+fUnpP #{v=v3ãG0G->cgYLb5KQxea{G16C7 &AT!V#^Tn+WjD<Ѥi @BP̶S125 A$VNA|;c=[[hww]o.i2kqvudov-]<YUSCX@eI|/wM'W3&BkSLo&%0]-R 6kU!3gZ c]R7s8VerxVUGLoM#P,w!%\\}Ew2tVkГNǧP5ڪ[]RБ…ZR8΀>G#vfrlϻ^[|lYkUAN_[D:|Ji=[M'G1! - l=5 U14듖&A"'ꡥ# 0+b{{qw^8XL*a5-]4 YiVx%T UԁWMk4 ":xfB N~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽tv{tBm];saႹ|[6G'$jYx*(*m5Dn5ڶ=|ڬgHU;>ltsLEɧ1(' wOןz'A]\eaoniO: *hਗ਼Ax[$k 8s48i>9h?ז9jKmi 80L6&fGmD,@2ƬdPPidhWangkY:GᬩWD?&Qp8(K91ouƦaD Į Ea%ٷ-׌L+I/iIda!S6IzZʡƅrB*iׇAju}z,&iMm&x;m`()#͢Xz$rSPeO/X=Ɯ}])+rmMdX)ފ5Do9㘡/7Y-!Tk9f RQ<@лkI~GSAoʍŝ+ؑvz'96m]P3CjrqmCR$k*ybT)ykJX55`D$THI)NAz=ŶYe!dI/i4gmw+v﮷[v&s1?zf]ݛy?/)Y2hj BK5E4øAZ$hn3Em@+YHP]vEiY"8v!"m*kBzVg? A_ݸG!>XMB93 d$WC 9cI ֢h@4>_#^xY▁Ѕ QdwF?WfWx`#$N$UEE"WN~tX]I4?.LofFF,fQ㦫-$cҪ} 0 ID[j T ARh̒@S4OT,,+t#)_$x)}װd38l.{Em˖zX xcgoWkR^pb ,3+hćIMU}JoAl". dWE%{OG-3{^7 ؘ^ޒJa/~ }= 8U8Y$SȞoQ˷4߬1+w@w-##>M:YA\{[]m;,.NK+,EW*Yےx׸w53՚zJ9)**dI1H D" U$o?.%{E%*]FbP:jkc_vuDr4Vw$)mmsu'UVGW,XSoN=Ǘd2[gpLj5yhcyg#9=;x7|ޗLͮ >& !$iX #OBZmyv0Z9jU;8ơu OK=/#3aC+ ڻ;qnjJl^W$8X}~p-yǘ~Y-l_ (-n Mp*[ $*Jts1ײm`ga<6].H⤌*H˽VUEv,F]}5GGOWh6vy\MeLoPH=a#^JZFYIXF8ocltvB%|:o=K{{9dlƇ 2ag6-DypqnOuQƍS6B\}$RC#SK^Yn`s֖w'BфjR5&QB(# H, 6}9'FeS{M|먊SMsֿ}ڮK)UO6V1ݽ_PS*EEWȡ ̉cWE:[Ía ѣ5AkڈKkUEh៉sAaF7gwCzn[ 1| >s챎LFڐnbl;vgr"42CibH&iӹ7$ִK HY flPF ){;vw.w_&T{/&CXP|JJ\(oڶݲMnSbeZG 9|V / 7>Z.=Oa[S,nj\-^ l:gW3D(wmfebKD* NQ3õj.TB?d/q:gG|֓5j͛̒fi3Ydch$ʳK"jhHD#Ƕ\m=ij,aRBR@I;6q0UP,3q.5|Ц;gꭉ*"lor3;֣r;fNa[$9ma؅ډI+ܲA8m}pxٌ)wZRV..M]+Q/=Ou=ݧ~5g =nuxnۉ6_=|0R>a(ʊhg]˺0õ]ޱ'`bX+z1QME cx"0RiPkP :i{vs|mӍwg:i(R)jQ\u|4kڽ!*jсWM cf9_۷K'}7 ڵU$J?=eEq vHSuI>zZ: ׸=[>ơvk#Rq252)m+ ˜yi7(ZGj$f=̲,jPbhr!{Wݢr0,H+kAD|7ͽzwm_7omvmR_^d'4:fP$%Í5mY^Wwc us׷fi!"T|q=\37N&J!6ttn͵7AYTKB6WΠEI58ͮ~イ;j򸯸ퟎ#vn?ae鱔i-=BF8M@l~n{s=y uYb@.݋H " mtAJHt/BڕƑ*M5t$cf|lz{i:ϫwn҆nAM㲋IW%%"vӮ(Hּ(kXmfKv]rS0@cKf3<"FWґ QjM]S>oqչljPMhwPC>W3IT+ϼue:U)(zíD[B%Fdu5 TZ'X~ʭ+orD'&8 zʸB1QE Ut'x7wMaoK/%(@ xqUAꙤ`㪫LjK zIzWZ/'@mGx.娩j/,44nҴI?_hM2茭TT$>Y.ʑ@ex~wέK{^/zmʽYP3SUWn|u`, + }9kegm⻌%פ!6VZּTTlq$ )PXRTEG|Ce,vnm4vͬH'Xer'1l-E4 I6Nnw|5+_?=-{Czu;{7k*(cfϐq )p[cyK;VA:(m\R[v34.TkF/jxN:1ܷi7 Ԏ11TSCv?}[%k{¦L؊Zݷk5\)pU e\6aAS qaf<`isb #\W|z~ھ޻[|o&nOmj7Us:iTMW#c䂜!X/F6]ۭDm^'dd2HFɖ̷Ÿ<9.;Y&edʀ#/o%Sx~>v[qm*FսC jďȟyFI /q۝mmlvkG`搚GwhAˣ,t3-&˶,duE#Z蒂JRDAC@ZKZ _TK`wΦeX>oIUS56!ULyE5@Eis> -Y /, 7nV)"RZi-r,.)GCWR=Z\|MD򝶽Qfx$Z~E;nlmKO[у!46U9o˫c'8eY~ƽ@ͨDvs)Ajʨv3 '!xx ཀྵuM:ь*5i0S&9'7{t>ǫ}ՐP٫E;%fBa4D8H`o١/t(bi\5f=+! "}qgS˥q,b@r(z*;/w uPb vb6BeJHIK.IV7-ąHךu:_6cۣty>($P#^oԝe;s_ ;/gu7-0}{8jr=Ϲjw.Oy-Z`O 6$IF'wU.[%D3 X `)AcQiQ$N鶥r#M @UI z2=N=}l>roK;RMOj:F!p4{%-d7ʭr 2XxjRV:IG59Sm/0I|oR u kX#cSM hn=sN-cT,ww#lTo(D\C#M ]|{dV:FKlxƑkA+HqL;Ϙ{8QʋK~$9N|럖fv~wh=_Qu^fkj;s E!FjXRy\@h@hn,NYdo_Ժ,h(̺%bM,_'4e ե5CJ2 JiZ,Cg4Y穏⥏q`*UTM ѣ G?Eu] J@@S Kԃ#N!h&X/ay6AiJR0 Ѫ =|;o YWQF5lTugmd3lml 2 3!AtX3A&SYdi}Ml?hf1ᬹ%YWICWBĪ3-R}up PP(T$V,I'؟?۹O-8~}.[jf۽ͲGg.Uك\}&[&Vla$h>ŽD *̭QL|GU[g>n۶V3(zQTVϵՆ$I(>˜*y^UZ{띿7e%uT 3(95wMYٲ'v? @tNs*ߵ2ssmtہU]b^/[.V:4e(3IByW4ٳ%Sʃ[D,,dk j9br@uSY]4yˡ,Ql,څM/a/+XFp's2b54nRxm%f{8W%TU(5Qr)EcԪ U=6-7KK*VO_t/oυ]>QP"MUT3+K %孔0JERHq726ONeq:aY u.D׏Fd6n'wG]{|.2]kUKw˚^G#a/0XwP-`-G-/ -n PBKs;ynf֑³JYcieԓ%:+gWeg:iu5FD6q\ub\}kan dtjk4tAs67 }rL|!)N@ jݱv5 -be 3J]?k~? lrcw>d-s=L]_FaLxVRK`_盘Im$Yf +&"s<$B`0Oh&ܒsA%@\CVI4>u!W}X*뾨݌~u_vgeЗu)-[kTd$g`1JE+E4shWs,ە>vhD4*ʪVℭj+Pzꊶ3IuUec`#(xǬ0,fj5f/Q٨+)fj+iZ j)R]F5#{EfMe(*ij#lE؂V% P?-L : aM^6nnL;)&a4qyTW\:k5 *^I]o[ʍ!yZE @ ؔcU2rthԼaw~5 E%G5lhD/6KMc$W1q)>`|@uCiU`8ch+"d !5aI #V=dRu~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~qwHѤ*"(%T x߀$qh8v ʕ1V#8թmğo1X$j00Ka\~|gi| 2PS TNRj'VzSl?%76CC 0U%7-Sc(J#V?@`~k>9*ڍ N'ul6G5Iy~9 6{[qYnICZO:'ׇNZ"zlMe <<ON>]=f;D6RX=qX̲ 5f' Pi} =E:,@v>@[}yj{٘A}h)n&㔶-MrٸȡzX [D r3'U0Ǝ熥fT$uwጨфc{-1n*t:jX0 L&QX_[g$vﵱҳNFӸ}|kѿ 㺣m_ÊI5PժRWc [-m\Iܗ8U͝!-G<Ѷp!`55tzj6ٟ%b/c QݽMϽwx^ ]= ћ$"=9N)L3sx7eط7{OSZE&(H*N2fv&Eu% "EwկEd*V,hH8>/]׸콯nQP=j6TUh#X+YTgI*m[ļ wdoiG[3+Z]ꈂA`i:]Jn?rOݱ}ӋM˷sG'ʼXVJf3/wmi4\F7x9"BY!r% U {)l${8$3"ʨdR4场a{xzbvnZpm$lt:͖i'x^CԈ샗"6}ެd34qH՛J@;}cbjVDfsHr[S˽ìJ>9;ۯ4sEvؖmѵMy2Vd^"zھZkMۘ.|d"9d@d*BuV&)z-t#f5KnuQ^&zavNଇ뚚Mn്EvM%WN'Ock=u@Y!Z)bqY8ܭ;w#^Y&G9+-xdP$ӪpK>S.tS^ڴygb1۝{6OnIul "i;WdrO =*Iⶮ4kYl׶X'j(l<0^v@Vy˙mynVs-Uq$5 'M:L/jg!y>E&~tlI0wG!28H";sll* $iFJ'v+vR16_ cT α)JMJ“V-yޤW(ԠGp4cǍ WKv۔8ۣpmm-_3{Ɠfclfn1a63%TA$异)P! 6I dLN]"k}$:Phwaw\e A>@^"%?buTa)zorui{Sl:՗gYj8&xۍcOOWڪE2+;+(cYM/c N_#Xn)miAtImt Z:v+齳?]Kwu_mRm ^أ%ayޙl'?ècY Z&?5^Olێ/€3Jh@FgW.ϧ=v{'Mu]2FEuj\4 kЇؿG/4=Xf[ʻ( ō#t&n^o[T P ln-\}|"v^6]I.DkS%VN=4TCQKDA,7w\M+\BtRuܻv! Nf!Ya2tWC' EW1HNjV)J#ݻ)<'`t7.K ]v+dV,"Ro_rح{GVANթapU^HʑǻQգê%hVN45Z {wcF}l!. ͵[Y5{aRb+Tu4ƆYrȦ}tQ$O 5SHىfvV `jq iuxҠ")fՅ (gٝ;wClk)6YG!da'oL]4E?aL0G2yjko6LoܺBMVKx+J<6S!U3SwDiu,E#~Sa'y>ո{Wv^cڸ^t5Eu,Gu55d(Ll˗7WVfJ)`ui˙ B[%/59vڊPTC{ M7fGcSc7f{W.J#+U/ak04T)Y5\w.&d]-F4%ċ MDSsN =mM-2M+Pw 3j¬(hzϰv7uu;5{;~n]凥foݐLGF[qy\9ƂA4͸4(W#HU5I'̇14ZY-٣ 55NNbQl[|m2>ޔYLEwEVZK^>g^ۛ6ck}߻iG1U1#OQHy;7=.I>e"UPapHK]sv r[ N~W%VSJ+SA\{faosfss;KmW{#hn Em4Gw$vKl^9c׼=!E՝ۼ͵2rVjBx$atW7;F"]X.gGCTAmkQ4t=mA/T5XM4ݭC[kd]1KGL\4pۑaeY[68 1a gʟƤԎ=vb@ ڍXc'4vҚxKU@G_j>eMӀyn,wG/gwUti_TA#^n!,j>8=K%bI񳟽l`6;qC\y/ԑʜׯ\)(j8Vo`o੧]SL+XhEy].[֊kl_Z9H2HG=<{Q:u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u#W!~Ki2hm@OVE蕥Hպ2Y4eHQᤤTxlb}PQjHfXkͼNj0>ˡ]1o3C?>Fuip+$\+E2/fbP;5bn R=.rSu/ zf: HzZ?m@'/S44̞ul~'ެK3 JPL@5$u9X+;joIk6Xԧb?/R:1R$~sIIe p ox.?/ŠH pCO}5S{IME0+su-JM͑lv6;+p E^:-MQJ_Lr6lmqXKW˜b51 FTH/_ 9t@RA>G V=sd7e>6. 씹 ~x׬w:GQHWH1a5q{>4+9MixrBT펻5che'-b2(m6KMnÊG*gUTO/_rmhǖ9ḏo!dju䛅&)]> 1nbz7e*MjtZ C)נZNn1ۛnMٻSm;?uxdz*&{$dqUoalLEa*I@*b 7+"$I  kђU%ٙH >+tT3IM)k zđGWKLaHca$zʰߌ"&j^C^j"m[CRQ Q4o` #-bZ1I:(pBKwq|zT]қγen8T|Y-X}#ƒxAo$jHUVV$I&4~ Qۂ)V(A}kO^{?4)7:qb+v]GL 5vO.TTEOktX Mn VMNG n2 {" @UVQ$iZ8‡1]]x}~5nMQ]튬e1g~!aGoFj$*UWR<"z8E&F)ԕ}x C;';v7/:;=U [J\X긪(*kZ(ƕ.$;\pLU*Y:=;O:p;!N4teBvHЭZHAE'̃Xpn67dpUT錩ǡPT5(bqJUΒ%NsPi?3c~XuNԓmuVoygNAmѳٽO52C-5T*N5եOU1yyPA IQ6,#g%.^R(N"6PWj" i wojUWlo~w?i;{7ғM_늭$S!i0K#iFIjxZ^!I$޻`-#,F)vxkihmj^Xh F{oQ]׀WWMA'{+-Lhed*hf**"Xe@HXӭkl.`2ÅJ#h 5胘6]w[ӡ 58׷#'.3~f=J>y)/gwnoq c#MQWG'HdK$Q0c(/,,{k`{nfHG$I%Hjn+طl9a(:xqLPWap0@:!7zo]Cl\nJo|ٲœiⷽEE.WnTBI^WU#U3!mWlR^ݐF ZU)SJMcvH'PDPAP*@B|4sf68C>Mq=ƞtY\NZK[]]U:Eh>ʷ#>'3M;4S<̱MiH߾`ȡZ, K"3B5EhnXIDA,z ɨūqV{┘z=&m\&펩4+umJE5{rP5,qRW>W:v@S$g[bܵ ÿxZM3fRhR=C;߹[lݖ*ihF+')51}Ż~Af[7Po.GZ KVm M(irA)LTTPӄs,lvזEge aZH:E`SHӗy{{ fRA%;JE\VA4# {';fv{)gn-F'%xu@i"JZJj*)('oە۾1VWV:b^_a5{7RO5X56е$lȲ!&`@ GQTtwTt&'OmӀnݾ1˞m 7Ļ|S ndV'dTOܘvf#KA$4uC-.|֏=uf*`moU]KL3K&"2{ҢFSdž*L\{YlϺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uQKSNEBGG<kߺڝ,klyU'{eD BUo*\ܵ=eU&++ [7GUiYAwUqžs[ĊiWFA΂HܘPOΆqϢ9C }gI"NӓAtvSEqL4 ubX@'/G åVH& XR؊JɓV ?6^V6NۊgʕC -ƟG?å_oDXSQljc"1PP٪Dk#H(՛os۹d.5נ'2m\HyF0*-A;qyH-BьۘT}iSE6 p5]Ki+D*PG+6<[p1 ٣"wZ5Fr0P0 .F;]noޕٖjtTQ%:RAGEEO4H'.[xƋFkdԱ$ЪM%d4<*I5#ÇK<.޻K!ˢ7_bJ&l,Vhairo+OR1N#գIܭR7@O z(E$S-Tv?# 4kKFq:1ZR )EdQź7f%Gp56ػ~[ȓw&ɫU+6>}g)NYd =s r"{{A%YhIO^h|Uua.NƜ kBJ]CR(؛xøݳjOKۤnt[쫖I`;;lŌԐSЌor9&y彺[Ou1鰙Z!YJ"Ve}r=5C%FKLe20rI͢/Т_LÇ!Vuv֎ڋ!QUnle$ԆRR)#Oydsdr ϴW|GJ7JhjT0*%$݂.LS T j=V0#&쾽n꭯m]AKWYqQ*ښjyg4O<=柨u IgfTt+iP;ЃRbԩ4R[(tz1k=uwbUv.{un-ٸ1Sfd F`4eryاg4mD˻^ikelʡbhlu4[ yHn.QYkuST$Dj IH!lyhĹRJ%'1j'+S$+DУE,!DS hj~X2~05qڤ i,ME%Ov#W!]04;HfyrO>˥Ydgv,S1',I$rz%FBTaJb.魩HJyc/~ʰPC%YpL 4}xz YD@uj/JyxAt$mJ[/QOOi@]r㤒TV TJVU94eөos~}I'* *M)t,mRG˦̤ EVjt`]d̨tdVDZubʬktܫ2)i9 ++2{%}4c,$|JijI-ė% VI'BԒПU43yf;`7UuX*ߑt|lNQsn6= 趈N fhii 9*PхI\w;a\.o b&o' FFD.K&o{VŜtxY ~`eeT%{@Z`ugjwGΤܛd%/LjvGo 0jr݇.ͥ$j:Ђ;xU,66;hUexYe[}1hÈ6P_-}Ki,T0[r4wYT|VF>߰M=7gH`lJ(Mg7YM@f+j9a50~[7I",,--É{XL!ҵ(3ֲ_ = -i#慛w\_J7^ؓgUHE1G8]َt/d1-\6(=T 4[坶n,1 0> 1b@m,R+qeomo-Ft z+?>/ ы7umYgxWfsu>O~ZFJ2Ɖ2iB[rof5^J7#]`Z^:U*\Ċh pjUƽ >piI- !Uk+/\O? MpG]kx%~ڑcn~Y) VL&ߌN+?q #WYc[(!fkkODI%Ҩ *{궗S^5;D-ǹ&@jVR٥݉];7b۰3l"ivnٙ]I4Xsuછret]yIS&hCk6żUV6b"./grε@#$|&P9,p`8FJ Tw\Ҭ+^G߂'|:['ꋳenia a%Q>j50,|wa1,YQmu[@Y{ox3L5Bt5~AԶmSWdCУFE R(#(ۥj#_0=o.NXbv'c켖?|gAU ?~mJ#G[>"x}]6fKm4;XDj̲-SY:#ܶ;.\K ]>2M–#fR]4e 1IMo{O[|Ubw]v먓pikwFl(ڔ][]qTDII loڬwrv`@{AT$*x"WT\%uumoi)4>%&ӹXŸ-TѥńW]ّ20ˍ⪟sTujN^+JSCLa)Zxu-Xoלl8N2xjE.n;d5&$ ӌ|zK=ScB@8FfULSJR63*Nec)%pE飒A)>yc @(5Mt*Fx9"h> ƿgF+$(X!"$ɧ $~oϲL9OJ'ȐɵGؾ슼NfvTֺv*O&)i\JvRK t^ė$({$WH#ˎ'̟vwU =rIh\#$-ZIEsOMSbLE.,T(*FA,b3{q ^cE9 \['ٶpN١S Jmfv7>^iqNta81X=w.Z;UW*-|Jס,am^r̡$АH)+ͪzUv5cv:LsnjuDL&* %|u>%qK[Lđ>.t mqɎФT]JnViB2'OY|OLC[{ {q*~},1'zXa !QbbPh#4P@aoNߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽tG~H0?G wz.u_mź)T]`#킺W "]y~XEYjGSQ?6Ӷ4p$Q[>K؃;׻v&]1gt4Te.N /XE&A 6wi5ZSV#U+O 7heX4Ȯ+C_.p9JNwM[SMC[ EmCwd QIbGPZjEP]ߞ7,ky10Fxuy7>1 Wbg쮪0:K/G G7dZ;GajhZYpRIh >6dtk1@%> D紞{}Xܵ -x5?5C4#i|Ǣ{CgTu43Dz9;#dxMy=|λg1Xٕtc?ZQ*d+C- a.|;#x RHS ЩYC:Co~fv&2XIv& ģ0,YjB i^餦y&YT85}m}mn$JԮ5xqӍKRMA转dd-XܯrBqQ@IVػ`a뾿,2}\+jmM]AC}ח5t.r2w7_Jcm:TF;+wDg!ùG۹ w,CvN|'Xd{+mZ_ CgƊWA]ܕYkmfwsn df:u:S{BP4UO!E Nco-A}:ZxF=JTRW\kEϊ *4Wn7]+%F#*°4g.yw };k#]Ӕ|_n%>RHL#(x/]Y2ZܳO[,\!14*c8b?Ќo24Q~4:diB*C\5iywn/\eC vm*zlGxTچxFtX yݒu/܍ UwK&J*tWE2}Z-)֑2ŽЊb' I6 /"=ϰ%'xvm0}g n)[=U3$G^1&J)BRŷO3n۝/%#ƍ< $lv8mw;}aўŖXصs@$i@@Ց՛uůuG WU7eV" mL0CqnTS=?fk*q9qqt9IfkU73"R Ԯ;bI]1)O IDj$gU#'mWXl~}~f}Q5. cz{/7N߽JeG-CBI@W0yn3G [yEWSnVOJ҈൳H`[@]NlT5'8$Ť7r.[OS|uosuTU?ttva`xtgz}rR `\2TDQ)/,g"yp壸D+yqkqY$'F׀ yt]Ck +Jh[Tm%#@U"T e=gQ;?>>^w=_")nܛiqFn;++AUK_ I 5RD:{%ȉ;;:1&g\,W̔*d_xCQjܫ|ɹ&DzKgB ƮTƅɨ_;;}cmݥ\6Eך**V}O-9XFNS_Q.jٜBe ՉcuAkBƸCXڶ:bJRQAýl3켶:nb,_mRmťnsceLO<. F=ݷѳZ'0lCq<2Dt;(XC SE$f˻Fo׶;TRr4,*,Śp|mioafǭV}2Sc*IQ+a:b9F)dqv w/#WM<}84:v DJ1'9?uLo+wuڧոv@BR[q{59deq"#uD Wՠ}HgfGO#t<>/++60(r|'r?`#=Wn)oSuMٰ+^w,Wg-6V-/XѩxPXF[ &}8T$;qƿGW_;|o麼vcSMQ76h)&vJ&.\T. ?mb?-@+O]?A1u,8v>:*X j::JtT4UDPf?Կ~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ_ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺEΦ+ݕzfBVj NSbI?bN^Øes١hoE3g9jeMW;"ZkNyZf"{>TuFc}+d丕r l셕YcZ@ͼ\ vMEPk`妨I#:~Y:RǏLEQo<~ڏZfێ<.4ɈHJƑ꫱q`#~{ğpۼ.FVzEnok\۞J=jiu(akp?<?KƽGR )C=ۻm6ff9)qtU2L5,@ _0r0XY_%Q# 6lM2)#zգ7iNݴX=jIMA MK[ ,i$DYHe B|Ny[ċL{VtIrkN"Ģא0n+M&&O:_ *}e{K xFqrß! ci%hĒ,jRT;_o6ok9#2A"?QqN(kLUbK[9XHLc: :ߍ=عj v51]I,"EbU`؈g{oVqJzCGzK"@jP|3QTv_[v|4n z19 TWh]%f9IAloͼ*p#Ô 'Ćӂ o6ǻm#=лS#"9SY f=;_pn]LܧvJuIiF[kGG3OrKDFVܽ{HwHBԓ0SamͻJvɀ%dGVO td YGAIۻHPs8dQ#G~?wV6wPd:}nݭ[#A0J{ەՓMIK ֥Ʊ,@Y#Q G>.||Kkjz,-^ 4y\}v٫8L mv.&9S N.ݯy,`^\x9)VE H> עhy#r(SS{fT0 ~'ȶ]m7lc1]SY}|mtؽm =1y*K8˅Şow^!y#ބY9iHͲNb{~s \K{MlѼ8 T_ Ĵ(kK#:ku{ڿp-6*sULjbVI?xq!C-L 2v䏘,nF,Yۃ&b6e@:%M=K4"@/L$Nꇷ۱:nۋdvu5[!ζhϛrM2)2p+2]G}eq7wܢ[C VSw?y5К0$~X,#SZGy ,|}bI{fJzȔF,A>T[O׃)d/)+Ɔ(Zt,b%F41I"bC5FUrSFy Hņi4fբr=| }!R~v3rb &fs`qO)fqӄQKUoX@zK~|<[pZuk #+eV ֱ nyM]r]@ Eß*[tm~]Flv\.6޴Mn&l#;mI2MjEic)(m r_Wi654嫫@ nl=Ak])@4Jen8`W5:Ev\~doF4L)ݽ>nݔے'P4n1X=%j2e˕2gM~n:Xj$3/)Se6YEd ·d[\WKCu7sțq,Y`cP%#Ԉ ]=a{omQnn{3wlgnjU^\a-]VGQW*6 Au/-y 7=u gjP$[# 癛KRJ:k÷.iUmޖJ6/-@]R2!;v}]K禭M7oVhΛȭ8jݺr*:GZi㲎Ȱ>tǰ8oq%}ҙMBU#v>NG~evTTUϊ0V(j;OF\S,2'DwIQ2\g[*FYQ̳"bI4נ =پm$V顑"lؠ~,ZoZ[o/k~|_0seid|_hssJOzmV'O$M Ge+'ض`mw9J^x hWύwsҍuڧt16©ɩP@ kp]UnxۗkP#d31AESUUD=IIy=3o5ͶκJ4oK,tPY5&fc8%mwxEVVC Uդp_C]Iӝ-6D㗯j^:zWpxW`gX!݋*T,RH$QGb, E87ɁyH9!? 9ˣ5׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ_ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺZ|؛.籙 ݓ7K<`i RcǪT<iDԠ^GS۞yӔXw^O i5aQ/vyBw=RZ8Ed)L<4jUۏ/$r5 4STThpši b8k9'נ>)}^0dhgc$(E;:+y%"B"?u&)##c]<=@O]=#??_{)zZ 3HMrddmQ` S%~~ݛm̷}2u>McxXI1?_ϫ$W#eЅ ?^} B`t[\_WsW5x];K1w*'Q>*ejJI@xRY}* qG ]~cdPAgKSQEC)?q"j~7nm]5mfa*(Qև->!+JZyȗ廱ޯv{)wd4.T$ MdĸpۡAP%M+B=8>te?YMMl}V8cZ eUњڙ cMHpl|3m[%<155!pI Rdj^]3tj FkGFwL >:F+) FX9('OMB s|[11'OQQ.}@-t?GiNWicjj::-MC'r|fhHԾ;n@]aO:5k˔7FOFAH"܂L^"}\TqJ**i QΤƻ&; Otm܍4uT ɏzm.ݷ} +%١.x)4yOz|fĮUİA M;4#{\ku{ǷmmaР MRq|v&+yU{vn{=bCEEl'H袤ZS$hZt%mw^]\.HO4U4M CZtζŪ0i% 2EjUժZ T/GF\m]OZ\?I>㫦M0ݴu5&&hgt=EK"o SpnmԍMwEŚ.~0&5+,G+1,|%}w./7fܔ;W:q9 ]Rdqհs6FW;RH4 k$ᷥGt.] RhjGZ5rs S^Yı ,i38>`9&l;b+8q$d 4uG#bSD1]1e!+NB2xlu,elўDj>TRGD:/;M3p-> Oy0g[1yllTZ|Y9j]ee\RʮR$dף[=4WW j<_2 kk52-ݓvEkduޱ48L>6O}-4fp*YآۭyjSc QyOUժGR5 D˜Ȝ3/1"yDҀX- >I #=\|EL5%D5T2=tk=GHuf }ԈVJeO:=MfB.{#WI xdHG RNA5Ʉc?ϥUD%n?3;{8p]4riQg-=aZM{q5#jM T}:b? (v4 ~HQ_^c*+?noMG7Vz]qv@8j[tVghjq|L eUIRBb[kpc[,bJ⽖̵ QtПqv7Ș@(UI֮ J޾---;wo|T^|"MܴRvFڵStd)e"zfSP2XP#}MƬ`inkn椊=v;r|1k-u]Dtݣе-^suФk;Ky 7]5=휹genM,Baf٘53ủ1ݍ&f<ԝaݣ8jՃv~5m$GeF]e:.[> v 15cerMAcYAZB-K[w]O P$ίȕ=ph@V|Qؿ)3*Z|OA}ǰp?CGt (mmX)(#Ŀ|Jg{mEk4M6(o8$,ַ)`"Un{q xRRR 4U DuIOǽݒok7Ehk0`7e>ڛO-Yۘ&q$iRyWjcHxI7&VEiC454?ؽqٶs=ñ'-M .ڥYʺo,Fafwb 3 ےy;oH{@f~!IXA$apj`9L2=EFND iށu'9ދ-aV *4\OMՒy'SP8b4 u?oQWύr8GGu"5PA `min,l٦x%''9T@pWֺu{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺD{DbrT[tNJ\7 ,<J*"E3c?Q l].lWԬAPr@Z'4),0V&2?dj!Vk:n [r?)P0hTQoˠHWNLut_v^ڙFΞZȨ 8hղ^ KC/X4f 3{kM̏kygo $a N$T^j2E;8gJґFR+afPlmlT4vo~q!R@`EkХM^,WpEמ@-# gJU$gk1?~@H5'ѰzDgLuufb#U$UqI%.S^7k] ?DxV"^MປufWoOyk׶)-յ$TS\ Ff*zwyuVۦٺ[b#m "3 Z$aQtO=.mL 3BFz'_+2]i;K+{CqvQfj`MGxvf{pRt땳yF bZ:"M{86丷r{܍6- )6G$xY K#1 "I˨hPj6r5hLfF{ao^Qq/YMYqQiZj4Fc9Ҷ]?WSKKj ݢK*L8a+]E[fv'٘DX"<1ox]g7}ike3'G=FtIO_NꊀԕARQ$VKn7MU3T"J0a< ”A$dm-N?q1~JzSɕ|^6zJ:/=6[uL2|sy!&tQC{l+ 6H4!niyfmRȏ*4Lww(´GaB9BY]&DOZƊrY:?ß;obU|[=}W(g3;r䱴8}*U1f*Rɲn;{^9.-3Hy JZ"C{mlR@Dvvnm$;^/cՍb a:1~3]ٿq'MKKtT I'kҦyzx$gZSO {Szާ뇒WηmG,mq$~cAJE/O˭!ر[L{+[LTj'7~ F Fښ)(Q]%_Z֧F[؍v+ᨩ6chJz<~7Et4TFQ"( r `gs zi3~ڑ;AOQQ 0*;H }}m=˰#ܬ$} OźRPhIdg; \.-,bcd5 zx\&zel0TE]'qAlQ*WM &U,E+soq6ϺRLaNXV"qi-ڊ,%OBC'OYS(=QD[z#`.![Od/d :3v ұd!鵏bG$YGۧ=6ϦWWMOE/P :pԿ_io$1[ Bx~])';lc+*j*j e,fW9)![؞l>EsHFsKc2F$ 4ԗ<GNH4<+_|O./CTڄltPx<m''WG9_)Wi뭊QߡF2SS!m\9ܓ̰kԏ< Xn.T ϤF^!5m2ɡ禨]eVR}@aԞ }`ѯ.FiFOϏ֚urv>lI6VGMMZaS}WXv:\U $R=ZIsK6jON^c.`g| ŸRH *DLl)ʯڡP~ .=vY7SnjZFbYWa#7>q;(pT4e*̓ ͚۹DKk!22Dƪ̺Y],^Z_F=̌IcH&P*`Bvۻ vcUm6}MJ)ÄQ5TSZM\P!M\ɪKHմVvmV+m˰2)+<-Ҥ%\@IXy˷v0KDA]=림hF5 $$.S+aUk ƚ=z&Ve+/>eR#iV`; if;J ú@cy\"t'Gikqw lGcRL_I#- f[GK{7W`o۱6VnbKv{~-ݹqb74k6B9>::"J7NivKv9b6i$TKM1$bBUcKɢCY/-l{$-/nK7<"Q5||_kFo+qNlõ7=_b`b/7S*%0$/.ܽ^ͭ[N@PGy6Or #h[Y^ݮZ5}dԪhP*O^'A-Ǵ145]׏~쾹Qɰ 3Obs˭W ҠȵVMD]U`R@B;NYtmŊWv_pu5SuVsj59n0SG5E$ vWsZKi ;Hl,ͤ4ҴҐ. jKC  Hrs~.JfY'ܪ&eT'ʬkT<زfzۥ죻vWDaw\a+$tVPn(Mr; "aV)@t卻jbmQR1* 01M!vnknKJ3*\ X#WbUTPǫ_Oݳz3;bvhI6QO\Jl--R &j*6qY4,!'7ntYl)#VBKUZX`HloAH41"JRO5~]=@;an7Uv^[޻qK+Q`g۰*|dS=YfsGv+KkY#<Y Fg!P`-]7yu:ͶT`95*4RJRwE1LCA\C+*k#^/l~.-n3D)L _{ dDĔ Ed$ T[=ݞC{;԰qRWe%JGtiSDQ\KܟaFkxl0V}*Lx=D;ͻT,)O=?tB|]jv_Ǯݝ3h)by㙞lmM m\>fFB{}s]_3cgqkR/P??ܐhMsN1&x3O!ER#):@ 6Qāi=j5s>(ػclkbl$oG ,t_V]=5$M#zjf%>tnGJ~}{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ_ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^ jzj:"ZziY`d1 8d)cbH o~Vߍo#[=:ŋɫ6BI/>j-(AX_孭fKw.,\y[Ԛ0CN-n-尾Ik-ASSBe?2+;_p?+r#7dJPG?f 5REԞyA?YsuJ.Vkv$C([g)R c4ʭDѫ( J"*$П:uJGpx<?>Y'Xڞ(ꨚ)aAjc[.}o6rMi.8S&UKеAf?wnΙە2MEUzeEQidRM$q'&ߋ[(SahPGο'C}\> ]ؕ-F7fT!~laEbPgytny-7?g.w5=QmkkdAn'3GG!ORi/1+I3mq$T4I7ڼ=IMƫ3;Pr rq~Ds/~0;n ܑo7Osjɲ#7vxE68eR#,a#khެ$I$S iUm4xi-9ZkFtFAyV_mvwU`='ӂcn<@'[ݫ[mߘݳEAMٙ]Sbq̆&:x7 ",xS6S7m{A{ Hċxgzb4=FI=Ŏް b4•D>Vvxevep-$X&/ TbCHҀ BǓB$Q*bL|D u;1sLErK՞Κ#ʕԭ!?j1$:QP3NNdi@X M2Yrݪ;-GI N"ePoYHZVo*z_S.ݽB͕8ZC6/mAXeܙ89!G$f0pU%.*DqU\n-b:%cUd׭zz+av}XKQ,t)jݥf ,;I#314UTQ@_W.׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u'PUtVW@T ,R lC#)YHd`H ~:U=s/``عjbhz~V'ZTQ%L4ыD@O0^rַ̃V7!M$1^լ.jX̥X*Fk~7tUdl=e] #(8"2?bĨМw4sB 8`IE*Σ)eܹ8hEU"I 4L:mk1B_Lu Od3IEd]iuv6ܢhq HC4ˣH [\,rWZ^W;z*qԔo!ԔY٣8)ওjN9~ߥ7,jbE_g;{ n`7:4fbKD)ġ@^PhWe/c #11V`k1ZZf;#SWEYM* L2)$l<okitsCdp?p5 Ђ<8#$ h˛u6oz!h ͡4*H3-sl?q8xAeQ,/<7?Ns~oaoΪ۾| vfL6 8Mq Q;N$I=m[a;>oʱIbPpPH:*4W];qNns>5ȯG ++_n1=WWTNۋ{RgTUXݶ nZl,CZ[_ '0JKn:s2\JI(I._j =t\ӥK \jj`Cf|uvOvVT]A>,LBf冦4SHMUlMfDRۥM,Klv,֯Z RQ UMH3W7Mk^a? Iփi$L0\XN^{~|GpŊa3yz-bZ&I筽-\q2G$/yWcˣ[i̱A1LM$Tp4, +gvh"a,ѤhFfuUW~Pl-+%8z<64TʑG=uLtdUNTLTUQE:B/{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~'wnoڛ<9E5},1d*%Q맪x[6U0jvYaO-OXtY|wڱh/MtO J,SW Bߟgiq2 !}0zl *@_k7ARSz+7MU2ۃ'bj+py Ug%ePRSHKO̦9"DQ$B3:F|P)>.QSj㚌~QEYM<5E<G,R h)TxIpTHX"qz2GWPUIޚ$T-|2(7 @ţyT_tchݓ #ֶ^lq**Q꼘kX9"pL;€4N=9.ФLZQ7_g?oݫ196ifTAF# 5Ŝ,n6`о=FP |YT_Üg6tSW5tJ pKJ\\$ , `VL"GϬ`-WWg}V[MOQLqjHRwMwv:ƒ0]L *x :AN: [K0Am+āJZ ˪ޙɷ~g/Cyi$11 -Gy+>%ѽhq5]E4txܱ&Ryzly <ĨG3Ma1=U"ĬiI~ #w#RTfTݭ&]p;Lnt,oI\Y_>)K=[/ho WJ=20TxfLo=5E<=-Cly{9Q'"7hIVJkC.ԯP=otO$%zy(Z6h KUwp 7+1=)aPvB>`PI!vMv68MPx0:dwE+3VmЬ.S-Vc64jZmcTw.bM~TI!* :,,+men?i9oN]]zw]=8i⭇/B}d@\s`*IfZ"9ˡR@u ;Cec:jƬ~,.AJ|jn\T9 kkWrX$jCBu{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~P}۰z?_Y|{΋peWu& =NؔtˈrXa**k\GFJٸCulԐ/:P_[[܊Uj|=ڦg0E?"*+2QL)_`qH㠛[E4:ؖ^g>\=DTL㊢xE&jOlB d'bB+[)IϜfg r2:۝'gրC~Eb)%>UTy z:ErcqQJ$>u ػg{{.ٻǷwNқ-×<^tDYOS9d#{sikJ"Xv6qm`?̒}I9ls9ܛjGWe32_[ײ)^ [GᬧsKOrզ#Ti:Y-S5\ih.l;:hՌ%EGMS? yřf6_tfF4TqG/3{Nu~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽t|ٮVjU&1˖cssSSdj1ҟziYJ2)9bxn6[KG[{XBBMCR27=+ 7eԨN+F~ESv75oh~3UU35MYYMYQY;YF䍔+k˾m/2!A"U E4JK޶[ˍH!|*MWVc%7:sUqݗsDY,vMIHAW?zv[9ety7Uw t. @fhH31>IΧ6=I*3m-4هZ21v`u㯂!f{sp10Z9BU5imidxHWEI"*i[mGՑ2I3 1xsZ2 0Fcv.'e"goR'g$n,KJ= ;Cj9%IRE39meEnmUYܙ ImF8qR(ã3$622J2#N()'|w5sp[ 1;![wnmʟnv%\HUSNJ1}$Fn`TUV"MȷQQֺZ ]Gw^['|VaM5:mY[S 1Ei"oė'ݹw$[$QI}_Q{(_۶ٵon$e%|Uu2,3{TR9Y׆iΡDV = `ԩ~4~ LO8*U&>Suvj>fƱ,Mt-V#%VbSGUs2)*.9j̯k"QF&:#aD;vZ/ xD;@Y)ޠT5? ==e&[CG_KOYI> !$3ҳVAn\I |jH4QMnVq)1ՔTtU! ĂuQ!=YIB3ZW*ڕޣfXe%b"*8BLd:hLj'~=;a -*t|u=35¯|OU1*=X~ P;(55M-M%5F*ZhHI@;xw0nò$vquX֚bT&3ڋ-=mĺɔhARn$۸]Q6Ec?7&iL%Qc*4б:oox$RI%'fl>PIz⻶wQxFJPzӣTۣ-^<{mS=cHrVZ(1(WE~`{bO;pdkE_gv2- S?AAj#=C^m0r͜wfO :몌-Ҵ=X??q~yo˹;?}gvMu7흝%-&ۓ/Q]SO5YK_KloS$2T$?V`n $-O!r'\_! 5j?S0uΩ]cDA9jAdvI[aaUU+*DH*4iE@ w}{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽t޻~mյs~hj2tM =SIS0}>ͽs b B•ՑZ4py]-Ki)B}BML#%[zO~ rg7n󓗷n!6᪂DtlYH =cյ%YZ0E<,X^_S_Qcrݖ~.XfrJv.S4 J%fxݿig}Μλ h2H[ChjcICf_mr%ҭ CE@?z˴V#67`뱘kY'{:.]_ĵ%Fnߴp׻yn<̎4G)K+UH H#k"&5ˈnekxLVdfWTHtꐛ^Xwe4X8:GĒHCZ=w8 Mv~_7`Q 6*hI/vۘHiS%C{';qM;^!#^O6L^[=g#]]T'!8xj꯾I P7S|ԱWX"SW-&c.2b hx$HHՃv?ovYA[]H%1TI˾)onn!跥44HX8f" $KO HDHR H-,7S-cU%PMM<>#I_nWR.."$|,No\ ۡwddS;V; T UM HnKgs2wMS)e&"G:65Զ|RŒ0hB:cCأGKM:OTx}2SSZєv4 7+{[@3VaOE 3k©$ is3 q,$A^Ȩo#Z5hǩJU`H{rV:y$ 6lRٌjV_ʝE I0:ibd:iIHd#].-#651]nV5ڳj 8Ѓl7[P/A#?-AH4'7wKcbp]ߴ!O,R?LdM#MB3 ێvC]I1]b _"|HZKYg3~n5Td4|ՎJ:NTF +ap. b 6k[nV=Qè9?{-l&Yz}ܻpvgff$n5IQA.3MIIEFV4 U=LE7r++ wJQ|IEkO6jTtŗ$:ni}N[pŊ*|-ʒZ%\]&dz)ke+dȲ$5:lp{5 |*h2k\>mv-ٷ- i'cRrz/g(׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~T9tU ,񵤤ig%Ihd/ՒGyG4#`TW˧"??>_O򺋶s]؈q=&iTA#p@STڞBÐIl<$5$I?&|Kyהy;0E626?P:6 U䩦Z*:5pFM<вt6d7Qoy30mh+8,҇oi?V'*T) <"Һr ڊ P~m{X[Vb ujW?>=Gq$EjJ j)C h0P+jޢʥxe# yA0%"QZԟ2O>y=,*gT9F>~ǥ*&BlYmx(Q_{pxfE3^׬LO1ƆJh$i/7>ij(b?JI;2bF8?5~Ή䵚TkPF~/OV7v@o]A6ܢrsP U뤚ZxIeʋa}KIhiޅh~"H 1A `gFſ[EjBTAL"Ivj⨥J| HU(Y mqNG/쭢ʓKA%V?%Bn"˭OQR+OJyG׺qmoC۸ .pg2Y*@ y O/}h%?G5ƾ>֧Uع.;0Qj޴'W(:>K8sI7}hګ쪜kk#6U;r"K)JQoe~ m lfm A厤;#E`*R?n:_oxJ|^s;{ni7RS}%SQG ƻn>ȯ2<-Lb!A Xw[Kq3V0Ls=<W j[i\UfLl#8MiA`hx]Xr@>7$?mm~Ζ-H=Jⱶ>xzzKWˏy}Y,K/ڻ~19 Q4 <+6`ғI!+Z!jdyvԟ@"uqш>٣?騴Ij?6GNNi++6[unzR SEuʔr)c]Ғ 5mVqY;WyAq$Ԕ._/_SfS{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{{^׺u{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ@o5-Qii]HrK%L4qTkuW`>9KHh?ˈ7VA"qWN?)ftUKN;'fb\|g-ʆ9j0):^z/ ^xe6q[9I#`Gm Q_^ A 1L~GЁ e=5UW:jZhYeIV@ 2Om%KEX=۾--[ ՚}ӣ{::Z(l눧qղ MSR*(5›[>$iAsv?8oG{g[)m颵sЍDa'tdv=EFK:hf7UP6dd%&)؜M%~S+_!P6o\ekk*f>MlHZ"E4 F[{^ SSWFKTНEoZuuw]{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^lﮦmυ;jgANd1Al: .Z4(NGmxP0| یc֒̿s횽__UQt19"9z"폭ܙuT 5(X9]g658~ 棁'_d.yrNhcdiG Ԡs^jEQ8l0x(C%&fB,z@/~ͅyjzQT,ewhO߻Ц8E sJ^ӏNscnwם32wgF/ 6!VX_-=+r9 v†ƌx UW0TK$S *~]N<fv{ux|$ {﷾zݧmQ۹ZWa!LK}MNcg/ $XgBq5|ԅ moφq0=jWMNflm;#tDIdn*iVhce,8G!D@F(Egޭ׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ_ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uSOfSzB*ZUmem.*sIrXj?vp+4Ԣ@o=oͼ0 %F cͫp/l 5#"A44@?5>5ThandlerProxy.jsPK :~Tsrc/PK :~Tqaa src/index.jsPK :~T"v&&xsrc/snippets.jsPK :~TI~ysrc/generators.jsPK :~T'l77~src/arduinosources.jsPK :~TESwsrc/facepanels.jsPK :~T_[[wsrc/exthandler.jsPK :~TBo=hEhE}src/handlerProxy.jsPK :~T src/cates/PK :~Tsrc/cates/cate_25f02c8a/PK :~T3 src/cates/cate_25f02c8a/index.jsPK :~T?osrc/cates/index.jsPK :~T[$DD!src/cates/cate_25f02c8a/blocks.jsPK :~T bsrc/langs/PK :~Tߣ  src/langs/zh.jsPK :~Tߣ  src/langs/de.jsPK :~Tߣ  src/langs/es.jsPK :~Tߣ  ,src/langs/fr.jsPK :~Tߣ  bsrc/langs/id.jsPK :~Tߣ  src/langs/ja.jsPK :~Tߣ  src/langs/ja-jph.jsPK :~Tߣ   src/langs/ko.jsPK :~Tߣ  >src/langs/pl.jsPK :~Tߣ  tsrc/langs/uk.jsPK :~Tߣ  src/langs/zh-hant.jsPK :~Tߣ   src/langs/nl.jsPK :~Tߣ  &src/langs/it.jsPK :~Tߣ  Q+src/langs/hr.jsPK :~Tߣ  0src/langs/ru.jsPK :~Tߣ  5src/langs/pt.jsPK :~Tߣ  :src/langs/fi.jsPK :~Tߣ  )@src/langs/tr.jsPK :~Tߣ  _Esrc/langs/tk.jsPK :~Tߣ  Jsrc/langs/en.jsPK :~TiiOsrc/langs/index.jsPK :~Tf˃EE dSmanifest.jsonPK :~T Ydata.bak/PK :~T~A%%Ydata.bak/ext.jsonPK :~Tv;O\data.bak/categroy.jsonPK :~Tx11c^data.bak/block.jsonPK :~T)L =data.bak/translate.jsonPK :~T)L tdata.bak/facepanel.jsonPK :~Timgs/PK :~T] ] )ΐimgs/48687157c9ad4d6fa1243bebe8e94267.pngPK :~T8s}})rimgs/0c0b5eb22188494f9d7a2aa266c9e413.jpgPK :~T6vres/PK :~TXvi18n/PK :~TX {vi18n/zh.jsonPK :~TX {i18n/de.jsonPK :~TX i18n/es.jsonPK :~TX i18n/fr.jsonPK :~TX i18n/id.jsonPK :~TX *i18n/ja.jsonPK :~TXMi18n/ja-jph.jsonPK :~TX ti18n/ko.jsonPK :~TX i18n/pl.jsonPK :~TX i18n/uk.jsonPK :~TXݩi18n/zh-hant.jsonPK :~TX i18n/nl.jsonPK :~TX (i18n/it.jsonPK :~TX Ki18n/hr.jsonPK :~TX ni18n/ru.jsonPK :~TX i18n/pt.jsonPK :~TX i18n/fi.jsonPK :~TX i18n/tr.jsonPK :~TX i18n/tk.jsonPK :~TX i18n/en.jsonPKEE@